2012-03-02 109 views
25

我需要确保产品创建时至少有一个类别。 我可以用自定义验证类来做到这一点,但我希望有一个更标准的方法来做到这一点。验证对象是否有一个或多个关联对象

class Product < ActiveRecord::Base 
    has_many :product_categories 
    has_many :categories, :through => :product_categories #must have at least 1 
end 

class Category < ActiveRecord::Base 
    has_many :product_categories 
    has_many :products, :through => :product_categories 
end 

class ProductCategory < ActiveRecord::Base 
    belongs_to :product 
    belongs_to :category 
end 
+0

1.产品+类别是见到'has_and_belongs_to_many'的好机会http://api.rubyonrails.org/classes/ActiveRecor d /协会/ ClassMethods.html#方法-I-has_and_belongs_to_many。除非不想在关联中存储其他属性,否则不需要连接模型。 2.你可以使用这个问题的最佳答案http://stackoverflow.com/questions/6429389/how-can-i-make-sure-my-has-many-will-have-a-size-of-at-至少2猜测你必须改变:) – jibiel 2012-03-02 15:36:57

回答

49

有一个验证,将检查您的关联的长度。试试这个:

class Product < ActiveRecord::Base 
    has_many :product_categories 
    has_many :categories, :through => :product_categories 

    validates :categories, :length => { :minimum => 1 } 
end 
+1

如何编写一个规范来测试它? – abhishek77in 2015-03-11 11:02:16

3

而不是wpgreenway的解决方案,我建议使用一个钩子方法before_save和使用has_and_belongs_to_many关联。

class Product < ActiveRecord::Base 
    has_and_belongs_to_many :categories 
    before_save :ensure_that_a_product_belongs_to_one_category 

    def ensure_that_a_product_belongs_to_one_category 
    if self.category_ids < 1 
     errors.add(:base, "A product must belongs to one category at least") 
     return false 
    else 
     return true 
    end 
    end 

class ProductsController < ApplicationController 
    def create 
    params[:category] ||= [] 
    @product.category_ids = params[:category] 
    ..... 
    end 
end 

而且在您看来,使用可以使用例如options_from_collection_for_select

25

确保它至少有一个类别:

class Product < ActiveRecord::Base 
    has_many :product_categories 
    has_many :categories, :through => :product_categories 

    validates :categories, :presence => true 
end 

我发现使用:presence比使用length minimum 1验证清晰的错误信息