-
-
Save subvertallchris/d8a3f684bcf08cb7a2f4 to your computer and use it in GitHub Desktop.
class Person | |
include Neo4j::ActiveNode | |
property :name, type: String | |
property :age, type: Integer | |
has_many :out, :houses, type: 'OWNS_PROPERTY' | |
has_many :out, :vehicles, type: 'OWNS_VEHICLE' | |
end | |
class House | |
include Neo4j::ActiveNode | |
property :address, type: String | |
has_many :in, :people, origin: :houses | |
end | |
class Vehicle | |
include Neo4j::ActiveNode | |
property :year | |
has_many :in, :owners, model_class: 'Person', origin: :vehicles | |
end | |
# To create a relationship, you can use << to append a new node or = to reset all relationships | |
person = Person.create(name: 'James', age: 15) | |
house = House.create(address: '560 Broadway') | |
person.houses << house |
A more complicated example isn't ringing a bell but I'll think about it more...
If you wanted to flag someone as the owner of the house, you could do it a few ways. You could add a property to the relationship by changing the syntax used to create it, person.houses.create(house, owner: true)
, then you could find the owner later on by doing house.people.rel_where(owner: true)
.
Sometimes, though, adding properties to a relationship isn't a good idea. If you have a node with a ton of relationships of the same type but only a handful have the quality you desire, it might be better to create a second relationship that represents that state. For instance, at work, an account can be the owner and a member of an organization. Because organizations can have so many accounts, we wanted to handle ownership and membership separately, so organization.owners
and organization.accounts
represent two different relationships that both go from Org->Account.
As to adding a second relationship type, I think you were asking about how that would be represented. I think it's best to come up with different association names in that case. Like this:
class Person
has_many :out, :owned_houses, type: 'OWNS_PROPERTY', model_class: 'House'
has_many :out, :residences, type: 'LIVES_IN', model_class: 'House'
end
class House
has_one :in, :owner, model_class: 'Person', type: 'OWNS_PROPERTY'
has_many :in, :residents, model_class: 'Person', type: 'LIVES_IN'
# OR...
has_one :in, :owner, model_class: 'Person', origin: 'owned_houses'
has_many :in, :residents, model_class: 'Person', origin: 'residences'
end
Thanks for this. Looks like the original docs are down right now but I thought I remembered there being a more complicated example that I was curious about. I think I already understand how standard has_many relationships work since it is a lot like ActiveRecord. I'm still trying to understand how more advanced Neo4j.rb relationships work. For example, let's say there are multiple people living in the same house, but only one person is the "owner". In this case,
person.houses
is not clear whether or not it is just the houses owned if the person is just a member, or both. It would be great to see some examples of creating different types of relationships in Neo4j.rb and comparing them to ActiveRecord to see how they might be easier to model than if you were using ActiveRecord.