Confirm the uniqueness of a child in a nested form that does not work correctly

I have a problem with checking the uniqueness of uniqueness in Rails. It works great if I try to create a new object with the same set of attributes that I do not want to repeat directly in the child model, but when I try to create a parent with two children that are not unique, the check does not start.

Background

I have an application in Rails 3.2 with its representations in HAML with simple_form.

I have two models: Page and Property . A page can have many properties and accepts nested attributes for a property.

I want to check that the page should 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.

As I said, when creating a new property by its form, validation is performed. 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 executed.

Problem

If I create a new page and, through nested forms, assign various properties, I can get around this check. This, apparently, is a problem only if the combination of page_id and property_id is not already present in the database, for example, if I edit a model of a page that already has a property and I try to add a new one using the same name , now the check starts.

+4
source share
1 answer

I would try with validates_associated :

 class Page < ActiveRecord::Base has_many :properties accepts_nested_attributes_for :properties, :allow_destroy => :true validates_associated :properties end 

Update

Rails Guide in Validation States:

Validation is performed by executing an SQL query in the table models, searching for an existing record with the same value in this attribute.

The 2 Properties object you create does not yet exist in the database, so uniqueness checking cannot work. You must try with a special check.

 class Property < ActiveRecord::Base #... validate :name, :name_uniqueness def name_uniqueness self.page.properties.select {|p| p.key == self.key}.size == 1 end end 
+2
source

Source: https://habr.com/ru/post/1401416/


All Articles