如何通过其他模型设置has_many关系但需要唯一性?

时间:2013-01-07 06:02:23

标签: ruby-on-rails ruby-on-rails-3

我有4个模型:ProductsVendorsCategoriesCategoryProducts(加入模型)。

  • 供应商有很多产品。
  • 产品属于供应商。
  • 产品有很多种类。
  • 供应商通过产品有许多类别。

这就是我现在设置模型的方法:

Vendor.rb

class Vendor < ActiveRecord::Base

  attr_accessible :name, :description, :category_ids, :product_ids, :user_id

    has_many :products, :dependent => :destroy
    has_many :categories, :through => :products
    belongs_to :owner, :class_name => "User",
        :foreign_key => "user_id"   
end

Product.rb

class Product < ActiveRecord::Base
  attr_accessible :name, :description, :price, :vendor_id, :category_ids

    belongs_to :vendor
    has_many :category_products do
           def with_categories
             includes(:category)
           end
    end

    has_many :categories, :through => :category_products

end

Category.rb

class Category < ActiveRecord::Base
  attr_accessible :name, :product_ids, :category_ids
    has_many :category_products do
         def with_products
           includes(:product)
         end
       end

  has_many :products, :through => :category_products

end

Product & Category的加入模型:

CategoryProduct.rb

class CategoryProduct < ActiveRecord::Base
  attr_accessible :product_id, :category_id, :purchases_count

    belongs_to :product
  belongs_to :category

  validates_uniqueness_of :product_id, :scope => :category_id
end

当我尝试在命令行中获取供应商的类别时,它会返回大量重复结果 - 很大程度上是因为它实际上返回了该供应商拥有的每个产品的类别。

以下是v = Vendor.first

的示例
1.9.3p194 :008 > v.products.count
   (0.3ms)  SELECT COUNT(*) FROM "products" WHERE "products"."vendor_id" = 10
 => 8 
1.9.3p194 :009 > v.categories.count
   (0.3ms)  SELECT COUNT(*) FROM "categories" INNER JOIN "category_products" ON "categories"."id" = "category_products"."category_id" INNER JOIN "products" ON "category_products"."product_id" = "products"."id" WHERE "products"."vendor_id" = 10
 => 13 
1.9.3p194 :010 > Category.count
   (7.8ms)  SELECT COUNT(*) FROM "categories" 
 => 2 

某些产品有多个类别,这就是v.products.countv.categories.count之间存在差异的原因。

如何让v.categories.count向我显示唯一的类别数量(在这种情况下,最大值为2)?

感谢。

1 个答案:

答案 0 :(得分:1)

我认为这很简单。只需使用uniq方法,如下所示。

v.categories.uniq.count

要将其置于关联级别,您可以使用:uniq => true选项,如下所示。

has_many :categories, :uniq => true