質問

Aは、has_manyを介してリンクされた2つのモデル、「店」と「製品」を持っています。

ショップフォームには、複数の製品のネストされた属性があり、製品の一意性検証に少し問題があります。製品を入力したら、保存してから、新しい製品の同じ名前を入力してみて、一意性検証が正常にトリガーされます。

しかし、同じネストされた形式の2行で同じ製品名を入力した場合、フォームは受け入れられます - 一意性検証はトリガーされません。

私はこれがかなり一般的な問題であると思いますが、簡単な解決策は見つかりません。一意性検証が同じネストされた形式の内に従うことを確実にするための最も簡単な方法で誰でも提案がありますか?

編集:製品モデルの下記

class Product < ActiveRecord::Base

  has_many :shop_products
  has_many :shops, :through => :shop_products

  validates_presence_of :name
  validates_uniqueness_of :name
end
.

役に立ちましたか?

解決

のようなカスタムバリデータを書くことができます

# app/validators/products_name_uniqueness_validator.rb
class ProductsNameUniquenessValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    record.errors[attribute] << "Products names must be unique" unless value.map(&:name).uniq.size == value.size
  end
end

# app/models/shop.rb
class Shop < ActiveRecord::Base
  validates :products, :products_name_uniqueness => true
end
.

他のヒント

Albertoのソリューションで拡張するには、次のカスタムバリデータが検証するフィールド(属性)を受け入れ、ネストされたリソースにエラーを追加します。

# config/initializers/nested_attributes_uniqueness_validator.rb
class NestedAttributesUniquenessValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    unless value.map(&options[:field]).uniq.size == value.size
      record.errors[attribute] << "must be unique"
      duplicates = value - Hash[value.map{|obj| [obj[options[:field]], obj]}].values
      duplicates.each { |obj| obj.errors[options[:field]] << "has already been taken" }
    end
  end
end

# app/models/shop.rb
class Shop < ActiveRecord::Base
  validates :products, :nested_attributes_uniqueness => {:field => :name}
end
.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top