ActiveOrient: Inheritance, Edges and Nodes
Tags: ruby, activeorient, orientdb, graphdb
Published: 2019-07-31 11:50:04

This is Part 3 of the ActiveOrient Series.

In [Part 2](https://dev.to/topofocus/activeorient-joins-and-links-j2d) we investigated similarities between RDMS(ActiveRecord)-Joins and unidirectional links and joins in `ActiveOrient`.

Our example Database consisting of Persons, wo are either father, child or (implicitly) parent enabled queries like 

* Which are the grandchilds of a father 
  (`Person.grandchilds( of: 'Reimund' )` remember?
* Who is a father? 
* Who does not have children.

For now, we stick by our `Person` class, but organize the data with directional links and introduce inheritance.

## Inheritance
In the self-referential approach, a child is a child, because there is a link in the `children`-property of `Person`. If we have to decide, if some action is allowed for the Person, we have to query the database and look for those entries. Thats inefficient.

```ruby
 > Person.create_class :child, :father
  # INFO->CREATE CLASS child EXTENDS person
  # INFO->CREATE CLASS father EXTENDS person
 => [Child, Father]
```
creates inherit classes. A `Child`, its a specialized `Person`. In the model-file (`/model/child.rb`) we can express this be defining customized methods. As expected, children and fathers are persons:

```ruby
 > ['Andrea','Susi','Seema'].map  {|c| Child.create name: c}
 > ["Otto","Joseph"].map  { |c| Father.create name: c}
 > Person.count     => 5
 > Father.count     => 2
```
Instead of querying the database for occurrences of a reference to a person record in `Person.children`, we just ask for the Class and know, this is a child. To list all children, we don't have to query all persons, we just express `Child.query.order(name: :asc).execute`. Much better. 


The implementation does not require changes to our database-schema. Anything works with self-referential links, as before. And it is still static. So let change this.

## Edges and Nodes
The most common feature of a _Graph-Database_ is the presence of Vertices and Edges. Our present approach uses only Vertices. 

* Edges connect Vertices bidirectional. 
* Any Vertex has special properties: `in` and `out` which are arrays of links to Edges.
* `ActiveOrient` provides a method `nodes`. It follows the attached edge and lists any Vertex present »on the other side of the Edge«. 
*  Vertices are connected through the method `:assign`.

Assuming, we want to represent the relationships of persons, created above,
```ruby
 > E.create_class :is_family
 > IS_FAMILY.create_class :is_child, :is_father
 > hugo =  Person.create( name: 'Hugo')
 > hugo.assign( via: IS_CHILD, vertex: Child.like( 'name = S*'))
 # INFO->select from child where name.left(1) = 'S' order by name asc
 # INFO->CREATE EDGE is_child from #29:6 to [#54:0, #53:0] 
 > hugo.assign( via: IS_FATHER, vertex: Father.where( name: 'Otto'))
 # INFO->CREATE EDGE is_father from #29:6 to [#59:0]
 # then
 > hugo.reload!
 > hugo.nodes( :out, via: /is/).count  => 3
 > hugo.nodes( :out, via: IS_FATHER ).first.name => 'otto'
 > Child.where( name: 'Seema').first.nodes( :in).to_human 
 => ["<Person[29:6]: out: {IS_FATHER=>1, IS_CHILD=>2}, name : Hugo>"] 

```
![](https://thepracticaldev.s3.amazonaws.com/i/ktuv7lsieqbzdo1l9lg4.png)

First, we create inherent Edges: IS_Family, IS_CHILD and IS_FATHER.

_Note_: In `ActiveOrient` Edge-Classes are UPERCASE. The database-classes are still lowercase. 

»hugo«, a person, is created. The new record is then assigned through IS_CHILD-Edges to any child-record meeting the search criteria. We managed to connect Susi and Seema. This is followed by an assignment of Otto via IS_FATHER.  

At last, we queried the relationships. The method `:nodes` distinguishes between `:in-`going and  `:out`-going edges. The assignment occurs on the `:out` side of »hugo«. The `:via`-parameter filters the edges, either by providing the EDGE_CLASS or an regular expression, which fits the lowercase database class names.
Nodes work in both directions. That's demonstrated in the last query. We start with a Child and ask any relationship. There is only one, to the father-vertex. 

Perhaps you get the idea: This is not the end. Its very simple, to investigate the relationships of the father, for instance, to display the grandparents, their children and so on.

## Conclusion
Inheritance and the flexibility of the graphical vertex & edge approach open sudden opportunities. `ActiveOrient` provides some methods to ease the transformation for people (like the author) who thought »relational« their hole life.

This opens many opportunities. As in real life: Its often more comfortable, to live in a well grounded environment with simple rules then to be responsible for a decent path. With ActiveOrient (and OrientDB) the developer can choose, to work with relations or graphs and s/he can benefit from proven layouts from both worlds. 

In the next part, we will develop a time-graph, able to efficiently organize any time-based data, events, time-series and more.