I have some troubles wrapping my head around the following situation..
I am trying to create a tree structure, where I will be able to give custom names to connections between nodes..
So I want to have Node and Relation models. Each
Node
has_many :relations
Each
Relation
has_many :nodes
Node can be either a parent or a child.. So far everything was easy and there are tons of examples that show how to make a self-referential has_many table... The problem is that I want to be able to give names to relations, so that I can do something like:
relation1 = node1.relations.create(:name => "relation_name", :child => node2)
and in result get something like:
relation1.name == "relation_name"
relation1.parent == node1
relation1.child == node2
All the creations are happening within the model, this activity is not really exposed to user, if that matters. Thanks!
EDIT2: Here is how it works now:
class Node < ActiveRecord::Base
belongs_to :sentence
has_one :parent_relation, :foreign_key => "child_id", :class_name => "Relation"
has_many :child_relations, :foreign_key => "parent_id", :class_name => "Relation"
has_one :parent, :through => :parent_relation
has_many :children, :through => :child_relations, :source => :child
has_many :relations, :foreign_key => "child_id"
has_many :relations, :foreign_key => "parent_id"
class Relation < ActiveRecord::Base
has_many :videos, :as => :videoable, :dependent => :destroy
has_many :phrases, :through => :videos
belongs_to :parent, :class_name => "Node"#, :inverse_of => :parent_relation
belongs_to :child, :class_name => "Node"#, :inverse_of => :child_relation
So what you're talking about is more like a Joins Model than a Self-Reference.
Note: I changed your relation
association 'labels' because I was having a hard time with your naming, so you don't have to change your 'labels' that was just for me.
So for your Node
class you could do something like this
class Node < ActiveRecord::Base
has_one :parent_relation, :foreign_key => "child_id",
:class_name => "Relation"
has_many :child_relations, :foreign_key => "parent_id",
:class_name => "Relation"
has_one :parent, :through => :parent_relation
has_many :children, :through => :child_relations, :source => :child
end
Then for your Relation
class you could something like
class Relation < ActiveRecord::Base
belongs_to :parent, :class_name => "Node", :inverse_of => :parent_relation
belongs_to :child, :class_name => "Node", :inverse_of => :child_relations
end
The :inverse_of
option should let you build let you build a Node
based off the parent
and children
associations from your Node
instances, this is just a caveat from the magic with :through
relationships. (Documentation for this is at the bottom of the Joins Model section.)
I don't fully understand your association structure, but I think this should model it correctly. Lemme know if there are any problems though.
Side Note: Since Relation
is a constant set in the ActiveRecord
module you might consider changing it to something like NodeRelationship
. I don't think it will interfere with your program, but it definitively caused some trouble for my thought process.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With