Проверки активной записи: уникальность вычисляемого поля при его вставке

#ruby-on-rails #activerecord

#ruby-on-rails #activerecord

Вопрос:

У меня есть модель с вычисляемым полем, которое должно быть уникальным:

 class MyModel < ApplicationRecord
 before_save :set_unique_identifier

 validates :unique_identifier, uniqueness: true

 private

 def set_unique_identifier
    some calculation...
    self.unique_identifier = the calculations.. (THIS IS A STRING)
 end

end  
  

Активная запись позволяет мне создавать записи с одинаковым идентификатором unique_identifier.

validates :unique_identifier, uniqueness: true Запускается только при обновлении записи.

Как проверить его в момент вставки?

Ответ №1:

Сохранение модели ActiveRecord выполняется в следующем порядке:

  1. Запуск before_validation перехватов.
  2. Запустите проверки.
  3. Запуск before_save перехватов
  4. Сохранить.

Конечно, происходит еще кое-что, но это важные части.

Я не думаю, что изменение атрибута на шаге 3 гарантированно приведет к повторному запуску проверок на шаге 2.

Я думаю, вы хотите установить уникальный идентификатор в before_validation крючке, а не в before_save крючке:

 class MyModel < ApplicationRecord
  before_validation :set_unique_identifier
  ...
end
  

Таким образом, все будет происходить в правильном порядке.

Вы также хотели бы включить уникальное ограничение / индекс в свою базу данных, чтобы действительно гарантировать, что вы не получите дубликатов.

Комментарии:

1. Что касается ограничения, мне это понравилось, но я не уверен, что синтаксис правильный. Моя миграция: t.string :unique_identifier, null: false, index: true

2. Добавьте другую миграцию, чтобы удалить существующий индекс ( remove_index :my_models, :unique_identifier ), а затем добавьте уникальный индекс ( add_index :my_models, :unique_identifiers, unique: true ).