web-dev-qa-db-ja.com

オブジェクトに1つ以上の関連オブジェクトがあることを検証する

製品を作成するときに、少なくとも1つのカテゴリがあることを確認する必要があります。カスタム検証クラスでこれを行うことができましたが、それを行うためのより標準的な方法があることを望んでいました。

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
35

関連付けの長さをチェックする検証があります。これを試して:

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

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

少なくとも1つのカテゴリがあることを確認します。

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

  validates :categories, :presence => true
end

:presence検証を使用するよりもlength minimum 1を使用したエラーメッセージの方がわかりやすい

43
Adrian

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

4
ftanguy