Изменение проверки фактически не влияет напрямую на существующие данные в вашей базе данных. Проверки выполняются только тогда, когда в модель вызывается #valid?
.
Это происходит неявно при вызове:
.create
и .create!
#save
и #save!
#update
и #update!
И это приводит к тому, что эти методы блокируются так, что либо происходит откат, либо запрос db не запускается в первом place.
Можем ли мы немедленно изменить валидацию?
Да. Проверка действительно вступит в силу, только если вы попытаетесь обновить существующую запись. В этом случае ранее действительная запись теперь может быть недействительной. Это не разрешит обновление, если значение не будет обновлено до нового разрешенного диапазона.
Работа с устаревшими данными
Если вы хотите, чтобы пользователи все еще обновляли существующие записи с использованием недопустимых данных согласно новым правилам есть несколько хитростей.
Опции if:
и unless:
class SomeData < ActiveRecord::Base
validates :foo, inclusion: 33..99, if: :legacy_record?
validates :foo, inclusion: 66..99, unless: :legacy_record?
end
Есть несколько способов реализовать :legacy_record?
, например, в виде логического флага в базе данных. , Обратите внимание, что их не следует путать с ключевыми словами ruby. Это просто параметры sh.
пользовательские методы проверки:
class SomeData < ActiveRecord::Base
validate :my_validation_method
def my_validation_method
rng = legacy_record? ? 33..99 : 66..99
errors.add(:foo, "out of range") unless rng.cover?(foo)
end
end
Наследование одной таблицы
class Thing < ActiveRecord::Base
validates :foo, inclusion: 66..99
end
class LegacyThing < ActiveRecord::Base
self.table_name = "things"
validates :foo, inclusion: 33..99
end
В этом примере вы добавили бы things.type
varchar столбец и обновите существующие строки с things.type = "LegacyThing"
. Это на самом деле не STI - он просто использует механизм, встроенный в ActiveRecord.