activegraph
activegraph copied to clipboard
idea: polymorphic association handling improvement
Note: what follows isn't something I have time to implement at the moment, but I wanted to record the idea for possible future use.
Idea to improve polymorphic association handling:
- Update the
has_manyandhas_onemethods to return a simpleActiveRelclass that can be assigned to a constant (e.g.class Person; FriendRel = has_many :out, :friends, type: :FRIEND, model_class: :Person; end) - Add an
active_node_model.path()method (andassociation_proxy.path()method) that accepts an array ofActiveRelmodels as input and uses theActiveRelmodels to construct a query / association chain.
person.path(
Person::EmployerRel,
Organization::EquipmentRel,
Saw::UserRel
)
# MATCH (person)-[:EMPLOYER]->(node342:`Organization`)
# MATCH (node342)-[:EQUIPMENT]->(equip) #<-- polymorphic
# WHERE equip:`Saw` OR equip:`Hammer` OR equip:`Nail`
# MATCH (equip)-[:USER]->(node523:`Person`)
OR use path() alongside traditional association chaining
person.employer.equipment.path(Saw::UserRel).employer
# MATCH (person)-[:EMPLOYER]->(node342:`Organization`)
# MATCH (node342)-[:EQUIPMENT]->(equip) #<-- polymorphic
# WHERE equip:`Saw` OR equip:`Hammer` OR equip:`Nail`
# MATCH (equip)-[:USER]->(node523:`Person`)
# MATCH (node523)-[:EMPLOYER]->(node353:`Organization`)
- This would be an improvement over the current
query_as()+proxy_as()way of doing polymorphic association chaining.
- when performing deep eager loading, a developer could supply an
ActiveRelclass instead of an association method name. This would allow deep eager loading of polymorphic associations.
person.employer.with_associations(equipment: {Saw::UserRel => :employer}, :employees)
Implications of this change
-
Currently, if you load a relation and an ActiveRel class exists for that relation, neo4jrb uses the
ActiveRelclass as a wrapper. Otherwise, neo4jrb uses a generic class to wrap the relation. This change would greatly increase the number of non-genericActiveRelwrappers. In many apps, I could see every relation being associated with an ActiveRel class. -
It would be pretty easy for a developer to end up with what are essentially duplicate
ActiveRelclasses. i.e.
class Person
EmployerRel = has_one :out, :employer, type: :EMPLOYER, model_class: :Organization
end
class Organization
EmployeeRel = has_one :in, :employee, type: :EMPLOYER, model_class: :Person
end
I'm not sure what, if any, steps ActiveRel currently takes to avoid duplicate relations or how ActiveRel figures out which class to wrap a loaded relation in, but the EmployeeRel/EmployerRel scenario needs some consideration.