#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 выполняется в следующем порядке:
- Запуск
before_validation
перехватов. - Запустите проверки.
- Запуск
before_save
перехватов - Сохранить.
Конечно, происходит еще кое-что, но это важные части.
Я не думаю, что изменение атрибута на шаге 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
).