Skip to content

Instantly share code, notes, and snippets.

@subvertallchris
Created June 23, 2015 13:26
Show Gist options
  • Save subvertallchris/d8a3f684bcf08cb7a2f4 to your computer and use it in GitHub Desktop.
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
@andrewhavens
Copy link

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.

@subvertallchris
Copy link
Author

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.

@cheerfulstoic
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment