ruby-on-railsruby-on-rails-3validates-uniqueness-of

Rails 3: Uniqueness validation for nested fields_for


A have two models, "shop" and "product", linked via has_many :through.

In the shop form there are nested attributes for multiple products, and I'm having a little trouble with the product's uniqueness validation. If I enter a product, save it, then try to enter the same name for a new product, the uniqueness validation triggers successfully.

However, if I enter the same product name in 2 rows of the same nested form, the form is accepted - the uniqueness validation doesn't trigger.

I'm guessing this is a fairly common problem, but I can't find any simple solution. Anyone have any suggestions on the easiest way to ensure uniqueness validations are obeyed within the same nested form?

Edit: Product model included below

class Product < ActiveRecord::Base

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

  validates_presence_of :name
  validates_uniqueness_of :name
end

Solution

  • 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