多级has_many,通过has_and_belongs_to_many

Multi-level has_many, through with has_and_belongs_to_many

我正在尝试在 Rails 中建立一个看起来像这样的三层关系。

+---------+      +---------+
| Brand 1 |      | Brand 2 |
++------+-+      +---+---+-+
 |      `------------|---|-------------.
 |                   |   `-----------. |
+v-----------+    +--v---------+    +v-v---------+
| Category 1 |    | Category 2 |    | Category 3 |
++------+----+    +--+-+-------+    +----------+-+
 |      |            | |                       |
 |      `----------. | `-------------.         `---------.
+v-----------+    +v-v---------+    +v-----------+    +--v---------+
| Template 1 |    | Template 2 |    | Template 3 |    | Template 4 |
+------------+    +------------+    +------------+    +------------+

请注意,Template 2Category 1Category 2 的成员,并且 这些 类别中的每一个都属于不同的品牌。同样,请注意 Category 3 由两个品牌共享。

现在的关系定义如下。

class Brand < ApplicationRecord
  has_many :categories
  has_many :templates, through: :categories
end

class Category < ApplicationRecord
  belongs_to :brand
  has_and_belongs_to_many :templates
end

class Template < ApplicationRecord
  has_and_belongs_to_many :categories
  has_many :brands, through: :categories
end

我无法更新 Brand-Template 关系,因此没有模板 "filtered" 品牌,因为类别是共享的。我现在收到这个错误。

ActiveRecord::HasManyThroughNestedAssociationsAreReadonly at /templates/7 Cannot modify association 'Template#brands' because it goes through more than one other association.

如何更改 Brand-Template 关系来解决这个问题?

我已将 Brand-Template 更改为 has_and_belongs_to_many。现在我可以像这样在 Template 上写一个范围:

scope :by_brand, ->(id) { joins(:brands).where(brands: { id: id }) }

这让我的查询有点麻烦,但它确实有效。它确实让我想知道是否有更有效的查询。