Rails 3: Uniqueness validation for nested fields_for

北城以北 提交于 2019-11-30 05:10:02

You could write a custom validator like

# 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

To expand on Alberto's solution, the following custom validator accepts a field (attribute) to validate, and adds errors to the nested resources.

# 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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!