Проверить уникальность дочернего объекта во вложенной форме, не работает правильно - PullRequest
4 голосов
/ 14 марта 2012

У меня проблема с проверкой уникальности в Rails. Это прекрасно работает, если я пытаюсь создать новый объект с тем же набором атрибутов, который я не хочу повторять, непосредственно в дочерней модели, но когда я пытаюсь создать родителя с двумя не уникальными дочерними элементами, проверка не срабатывает.

Фон

У меня есть приложение в Rails 3.2 с его представлениями в HAML с simple_form.

У меня есть две модели: Page и Property. Страница может иметь много свойств, и она принимает вложенные атрибуты для свойства.

Я хочу проверить, что у Страницы не должно быть двух свойств с одинаковым именем:

#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

Конечно, свойство имеет атрибут page_id.

Как я уже сказал, при создании нового свойства через его форму проверка работает. Если я попытаюсь создать новое свойство с тем же именем и тем же page_id, Rails скажет мне, что имя уже занято.

выпуск

Если я создаю новую страницу и через вложенные формы назначаю различные свойства, я могу обойти эту проверку. Кажется, это только проблема, когда комбинация page_id и property_id еще не присутствует в базе данных, например, если я редактирую модель страницы, в которой уже сохранено свойство, и пытаюсь добавить новую с помощью то же имя, проверка теперь запускается.

1 Ответ

3 голосов
/ 14 марта 2012

Я бы попробовал с validates_associated:

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

Обновление

Руководство Rails по состояниям проверки:

Проверка происходит путем выполнения SQL-запроса в модель таблица, ища существующую запись с тем же значением в этом атрибут.

Создаваемый вами объект 2 Properties еще не существует в базе данных, поэтому проверка уникальности не может работать. Вы должны попробовать с пользовательской проверкой

class Property < ActiveRecord::Base
  #...
  validate :name, :name_uniqueness

  def name_uniqueness 
    self.page.properties.select {|p| p.key == self.key}.size == 1
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...