Убедитесь, что атрибут одного объекта в коллекции равен true, а для остальных - false - PullRequest
0 голосов
/ 07 января 2020

У меня есть класс с логическим атрибутом, который называется primary. У меня есть настройка проверки уникальности, чтобы гарантировать, что только один в коллекции, принадлежащей указанному c ресторану, имеет значение true:

validates_uniqueness_of :primary, if: :primary, scope: [:restaurant_id]

В последнее время я хотел настроить метод записи таким образом, чтобы он присваивает новое значение текущего экземпляра, устанавливая его братьев и сестер в коллекции на false, если экземпляр имеет значение true. Несмотря на это, мои тесты не проходят:

 MenuGroup did not properly validate that :primary is case-sensitively
       unique within the scope of :restaurant_id.
         After taking the given MenuGroup, setting its :primary to ‹"an
         arbitrary value"› (read back as ‹true›), and saving it as the existing
         record, then making a new MenuGroup and setting its :primary to a
         different value, ‹true› and its :restaurant_id to a different value,
         ‹nil›, the matcher expected the new MenuGroup to be invalid, but it
         was valid instead.

Вот тест:

it { should validate_uniqueness_of(:primary).scoped_to([:restaurant_id]) }

Что я здесь не так делаю?

class MenuGroup < ApplicationRecord
  belongs_to :restaurant

  validates_uniqueness_of :primary, if: :primary, scope: [:restaurant_id]

  def primary=(primary)
    if primary?
      MenuGroup
       .where.not(id: self.id)
       .where(restaurant_id: self.restaurant_id).update_all(primary: false)
    end

    write_attribute :primary, primary
  end
end

1 Ответ

0 голосов
/ 07 января 2020

if primary? проверяет, является ли запись self.primary? истинной.

? делает это вызовом локального primary? метода, автоматически сгенерированного ActiveRecord. Это не проверка переменной primary, переданной в качестве аргумента функции.

Тем не менее, ваша проверка не может быть проверена и фактически ничего не делает.

Цель вашего установщика primary= - автоматически сбросить предыдущую запись primary. Ваша проверка не может быть отключена, потому что ваш установщик не позволяет моделям перейти в недопустимое состояние.

Ваш тест пытается установить секунду MenuGroup в primary = true, но этот акт устанавливает primary = false для всех существующих MenuGroup s, значит, проверка проходит успешно и успешно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...