无法理解 rails 提供的 Activerecord 自连接关联方法

unable to understand Active record self join association's mathods provided by rails

我想实现一个模型 Person,其中 Person has one parenthas_many children。我也不想创建任何其他模型。

人物模型

class Person < ActiveRecord::Base
  has_one :parent, :class_name => 'Person', :foreign_key => :parent_id
  has_many :children, :class_name => 'Person', :foreign_key => :children_id, :dependent => :destroy
end

Person(id: integer, name: string, created_at: datetime, updated_at: datetime, parent_id: integer, children_id: integer)

1.9.3-p194 :024 > @a
 => #<Person id: 8, name: "a", created_at: "2015-02-10 05:53:28", updated_at: "2015-02-10 06:53:35", parent_id: nil, children_id: nil> 
1.9.3-p194 :025 > @b
=> #<Person id: 11, name: "b", created_at: "2015-02-10 06:36:31", updated_at: "2015-02-10 06:57:03", parent_id: 8, children_id: 12>
1.9.3-p194 :026 > @ab
=> #<Person id: 12, name: "ab", created_at: "2015-02-10 06:54:50", updated_at: "2015-02-10 06:54:50", parent_id: nil, children_id: nil> 

现在@a.parent =>

Person Load (0.3ms)  SELECT "people".* FROM "people" WHERE "people"."parent_id" =  ORDER BY "people"."id" ASC LIMIT 1  [["parent_id", 8]] 

=> #<Person id: 11, name: "b", created_at: "2015-02-10 06:36:31", updated_at: "2015-02-10 06:57:03", parent_id: 8, children_id: 12>

至于我知道@a没有任何parent因为parent_id is nil。那么@a.parent是如何工作的。

问题是你使用了两个外键,parent_idchildren_id,所以即使你从一侧破坏了 link,另一侧仍然知道 child/parent 仍然存在,通过另一个外键,一个基本的 one-to-many 关系转化为在许多记录中有一个 id,所以你只需要 parent_id 在 child 记录

  • child 将具有 parent
  • 的 ID
  • parent 不知道他的 children 在哪里,但是要找到他们 rails 将查询所有 children 有 parent_id = parent 的 id

以下是您需要在模型中更改的内容:

class Person < ActiveRecord::Base
  belongs_to :parent, class_name: 'Person', foreign_key: :parent_id
  has_many :children, class_name: 'Person', foreign_key: :parent_id, dependent: :destroy
end

请注意,我将 has_one 替换为 belongs_to,因为 child 具有 parent 的 ID,而不是相反,两者使用相同的 parent_id外键