a有两个型号,“商店”和“产品”,通过has_many链接:通过。

在商店表单中,多个产品有嵌套属性,我对产品的唯一性验证有点麻烦。如果我输入产品,请保存它,然后尝试为新产品输入相同的名称,唯一性验证触发成功。 但是,如果我在相同嵌套形式的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