9

我在类别、产品和品牌之间有这种关系:

class Brand < ActiveRecord::Base
  has_many :products
end

class Category < ActiveRecord::Base
  has_and_belongs_to_many :products
end

class Product < ActiveRecord::Base
  has_and_belongs_to_many :categories
  belongs_to :brand
end

如何通过这种关系选择指定品牌的所有类别?我试试这个但得到一个错误

b = Brand.find(1)
Category.joins(:products).where(:products => b.products)
4

2 回答 2

10

您对连接做了正确的事情,只需添加一个更复杂的 where 定义:

Category.joins(:products).where(:products => {:brand_id => 1})
于 2013-01-09T19:34:34.063 回答
4

有争议的是,HABTM 很少(如果有的话)是一个好的设计,而 IMO 几乎是 Rails 唯一出错的地方。

引入一个外部参照表来连接产品和类别,并在关系的两边使用 has_many :through ,所以你最终得到

class Brand < ActiveRecord::Base
  has_many :products
  has_many categories :through => products # This is now allowed in Rails 3.x and above
end

class Category < ActiveRecord::Base
  belongs_to :product_category
  has_many :products :through => product_category 
end

class Product < ActiveRecord::Base
  belongs_to :brand
  belongs_to :product_category
  has_many :categories :through => product_category
end

class ProductCategory < ActiveRecord::Base
  has_many :products
  has_many :categories
end

这为您提供了最大的灵活性,为您提供了最少的代码重构以及更直观的路径来获取关系任一方所需的任何数据,并使您能够实现以下目标

b = Brand.find(1)
b.categories.all

更新 上面是完全未经测试的代码,我刚刚纠正了我犯的一个明显愚蠢的错误。如果您在实施此操作时遇到任何问题,请返回

于 2013-01-09T19:32:35.147 回答