Rails 4.2, PostgreSQL 9.3
Model relations are:
class Nesting < ActiveRecord::Base
belongs_to :product
belongs_to :configurator, touch: true
validates :product_id, uniqueness: { scope: :configurator }
end
class Configurator < ActiveRecord::Base
has_many :nestings, dependent: :destroy
has_many :products, through: :nestings
accepts_nested_attributes_for :nestings, reject_if: :all_blank, allow_destroy: true
end
Situation where I create configurator with product foo
and then try to update it to add product foo
works fine. I get error has_already_taken
.
But when I add two identical products at once validations doesn't work. How do I validate uniqueness of product_id
in Nesting
model in scope of Configurator
?
My views are pretty basic:
= simple_form_for @configurator, remote: true do |f|
= f.simple_fields_for :nestings do |nesting|
= render 'nesting_fields', f: nesting
= link_to_add_association 'add product', f, :nestings, class: 'btn btn-default'
= f.button :submit
_nesting_fields.html.slim
.nested-fields
.form-inline
= f.association :product, collection: @products
= link_to_remove_association f, class: 'btn btn-default' do
.glyphicon.glyphicon-remove
One of the quick solutions is to check uniqueness of product_id's
in parameters in controllers action. But I don't like the idea that validation happen in controllers action.
Adding validates_associated
on Configurator
may help, but I would add a uniqueness constraint to Nesting
. In a migration:
class AddUniqueIndexToNesting < ActiveRecord::Migration
def change
add_index :nestings, [:configurator_id, :product_id], unique: true
end
end
Also see:
Rails 3: Uniqueness validation for nested fields_for
Rails - Validate Nested Attributes Uniqueness with scope parent of parent