Rails has_many :通过关联访问链接记录值

Rails has_many :through association access linking record values

我有两个模型通过第三个模型通过多对多关联进行链接。型号如下:

class Tag < ApplicationRecord
 has_many :taggings
 has_many :cards, through: :taggings, inverse_of: :tags
end

class Card < ApplicationRecord
 has_many :taggings
 has_many :tags, through: :taggings, inverse_of: :cards
end

class Tagging < ApplicationRecord
  belongs_to :card
  belongs_to :tag
end

我需要在我的 _card.json.jbuilder 部分中生成类似的东西:

json.tags(card.tags) do |t|
  json.id t.id
  json.name t.name
  json.tagging_id ?
  json.tagging_created_at ?
end

我不想使用其他请求,例如

json.tagging_id = Tagging.find_by(card_id: card.id, tag_id: t.id).id

因为我认为这会降低性能,使请求变长。

我的问题是:如果可能的话,如何通过关联访问将此卡链接到此标签的记录的属性?

预先感谢您的帮助。

您真的要在 json 中显示卡片的所有标记对吗?

也许这可以帮助:

json.tags(card.taggings.includes(:tag)) do |t|
  json.id t.tag_id
  json.name t.tag.name
  json.tagging_id t.id
  json.tagging_created_at t.created_at
end

includes(:tag) 将在一个请求中获取所有标签,因此不会影响性能。

我找到了一个非常简单的解决方案来解决我的问题:

json.tags(card.taggings) do |t|
  json.id t.tag.id
  json.name t.tag.name
  json.tagging_id t.id
  json.tagging_created_at t.created_at
end

是我想多了!

您可以使用已经回答过的 includes 方法来进行预加载,因此如果您通过关系访问任何属性而无需对 db 进行额外请求。此外,您可以在模型上使用 delegate。因此,例如,在您的模型卡上:

delegate :attribute_name, to: :tagging, prefix: :tagging

这样,您可以在 card_object:

上访问您的属性
card_object.tagging_attribute_name

前缀是可选的,以避免属性名称不明确。 希望这对您有所帮助!