如何在 Rails 中通过关联在 has_many: : 上设置foreign_keys?

问题描述 投票:0回答:1

我有2张桌子,

Item
ItemBelonging
。我正在尝试在
items
之间创建树关系。对于
item
的每个后代,我创建一个
item_belonging
来连接
item
和后代
item

Item {
  id:,
  ...
}

ItemBelonging {
  id:,
  item_id:,
  descendant_id:,
  ...
}

我能够成功调用

item.descendants
来接收项目的所有后代。我已经建立了这样的关系:

class ItemBelonging < ApplicationRecord
  belongs_to :descendant, :class_name => 'Item'
  ...
end

class Item < ApplicationRecord
  has_many :descendants, :through => :item_belongings, :source => :descendant
  ...
end

问题是我希望能够调用

item.ancestors
来使用相同的
ItemBelonging
关系获取项目的所有祖先。我可以这样做:

  def ancestors
    Item.joins(:item_belongings).where("item_belongings.descendant_id = ?", id)
  end

但是如何使用 has_many/belongs_to 创建这种关系呢?这不起作用:

class ItemBelonging < ApplicationRecord
  belongs_to :descendant, :class_name => 'Item'
  belongs_to :ancestor, :class_name => 'Item', :foreign_key => :item_id
  ...
end

class Item < ApplicationRecord
  has_many :descendants, :through => :item_belongings, :source => :descendant
  has_many :ancestors, :through => :item_belongings, :source => :ancestor, :foreign_key => :descendant_id
  ...
end

我的最终目标是能够打电话给

Item.includes(:descendants)
Item.includes(:ancestors)
。如何让
ancestors
关系发挥作用?

ruby-on-rails ruby rails-activerecord has-many-through
1个回答
1
投票

有了 ancestry gem,你可以轻松使用这样的 DSL

class Item < ApplicationRecord
  has_ancestry
end

然后创建一些记录

parent = Item.create
first_child = Item.create(parent: parent)
second_child = Item.create(parent: parent)
first_child_child = Item.create(parent: first_child)

并立即使用此类方法

parent.children # => [first_child, second_child]
parent.descendants # => [first_child, second_child, first_child_child]
first_child.siblings # => [first_child, second_child]
first_child.subtree # => [first_child, first_child_child]
first_child_child.parent # => first_child
first_child_child.root # => parent
first_child_child.ancestors # => [parent, first_child]
first_child_child.path # => [parent, first_child, first_child_child]
© www.soinside.com 2019 - 2024. All rights reserved.