I can see a couple different ways. I think the best would be to add another field to the table called something like lifecycle_id_original
. Then your model would include code like this:
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
When the object (member in this example) is validated, lifecycle_change_reason will only be required when the original and lifecycle_id are not identical. A nil value is also allowed for the original, because that's what it'll be when a record is newly created.
Then when it is saved, the "original" is set to match the lifecycle_id, so the next update cycle will work properly.
This isn't as clean as I'd like. My first thought was to use an attr_accessor
so the duplicate isn't being stored in the DB all the time, but that would have meant setting that value every time a record is loaded. I'm not aware of any on_load style callbacks for ActiveRecord models.