Я вижу несколько разных способов. Я думаю лучше всего было бы добавить еще одно поле в таблицу, которое называется что-то вроде lifecycle_id_original
. Тогда ваша модель будет включать такой код:
class Member < ActiveRecord::Base
belongs_to :lifecycle
validates :lifecycle_change_reason, :if => :lifecycle_changed?
before_save :reset_original_lifecycle
protected
def lifecycle_changed?
self.life_cycle_id != self.lifecycle_id_original && !self.lifecycle_id_original.nil?
end
def reset_original_lifecycle
self.lifecycle_id_original = self.lifecycle_id
end
end
Когда объект (член в этом примере) проверен, lifecycle_change_reason потребуется только тогда, когда оригинал и lifecycle_id не идентичны. Нулевое значение также допускается для оригинала, потому что это будет то, что будет, когда запись создается заново.
Затем при сохранении «оригинал» устанавливается равным lifecycle_id, поэтому следующий цикл обновления будет работать правильно.
Это не так чисто, как хотелось бы. Моей первой мыслью было использование attr_accessor
, чтобы дубликат не сохранялся в БД все время, но это означало бы установку этого значения при каждой загрузке записи. Мне не известны какие-либо обратные вызовы в стиле on_load для моделей ActiveRecord.