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
@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