验证对象是否具有一个或多个关联对象

时间:2012-03-02 14:35:03

标签: ruby-on-rails validation has-many-through

我需要确保在创建产品时它至少有一个类别。 我可以使用自定义验证类来完成此操作,但我希望有更标准的方法来实现它。

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

3 个答案:

答案 0 :(得分:60)

验证会检查您的关联长度。试试这个:

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

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

答案 1 :(得分:37)

确保它至少有一个类别:

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

  validates :categories, :presence => true
end

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

更清晰

答案 2 :(得分:4)

我建议使用钩子方法作为before_save并使用has_and_belongs_to_many关联,而不是wpgreenway的解决方案。

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