I have a problem with the scoped uniqueness validation in Rails. It works fine if I try to create a new object with the same set of attributes that I don’t want to repeat, directly in the child model, but when I try to create a parent with two childs that are not unique, the validation is not triggered.
Background
I have an application in Rails 3.2, with its views in HAML with simple_form.
I have two models: Page and Property. A page can have many properties, and it accepts nested attributes for property.
I want to validate that a Page must not have two properties with the same name:
#app/models/page.rb
class Page < ActiveRecord::Base
has_many :properties
accepts_nested_attributes_for :properties, :allow_destroy => :true
end
#app/models/property.rb
class Property < ActiveRecord::Base
belongs_to :page
VALID_PROPERTIES = %w(id text name xpath class css)
validates :name, :inclusion => VALID_PROPERTIES, :uniqueness => {:scope => :page_id}
end
Of course, the property has a page_id attribute.
Like I said, when creating a new property via its form, the validation works. If I try to create a new property with the same name and the same page_id, Rails tells me that the name has already been taken.
The issue
If I create a new Page, and via nested forms, assign various properties, I am able to bypass this validation. It appears to be only a problem when a combination of page_id and property_id aren’t already present in the database, so for example if I edit a Page model, which already has a property saved, and I try to add a new one with the same name, the validation now triggers.
I would try with
validates_associated:Update
The Rails guide on validation states:
The 2
Propertiesobject that you’re creating do not exists yet in the database, so the uniqueness validation can’t work. You should try with a custom validation