Rails自我引用has_many通过自定义连接表命名

时间:2012-03-29 19:42:40

标签: ruby-on-rails-3 model relational-database has-many self-reference

在下列情况下,我有些麻烦。

我正在尝试创建一个树结构,在那里我将能够为节点之间的连接提供自定义名称。

所以我想拥有Node和Relation模型。每个

Node 
 has_many :relations

每个

Relation 
 has_many :nodes

节点可以是父节点也可以是子节点。到目前为止,一切都很简单,并且有大量示例显示如何创建自引用的has_many表...问题是我希望能够提供关系的名称,以便我可以做类似的事情:

relation1 = node1.relations.create(:name => "relation_name", :child => node2)

并在结果中获得如下内容:

relation1.name == "relation_name"
relation1.parent == node1
relation1.child == node2

所有创作都在模型中发生,如果重要的话,此活动并未真正暴露给用户。 谢谢!

EDIT2: 以下是它现在的工作原理:

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

1 个答案:

答案 0 :(得分:5)

所以你所说的更像是Joins Model而不是自我参照。

注意:我更改了您的relation协会'标签',因为我的命名很难,因此您无需更改仅适合我的'标签'。< / em>的

所以对于你的Node课程,你可以做这样的事情

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

然后,对于你的Relation课程,您可以使用

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

:inverse_of选项可让您构建,让您根据Node实例中的parentchildren关联构建Node,这只是来自魔法:through关系的警告。 (此文档位于Joins Model部分的底部。)

我不完全理解你的关联结构,但我认为这应该正确建模。 Lemme知道是否有任何问题。

旁注:由于RelationActiveRecord模块中设置的常量,因此您可以考虑将其更改为NodeRelationship。我不认为它会干扰你的程序,但它确实给我的思考过程带来了一些麻烦。