Reputation: 41
I need to execute a hook in a rails4 app if a field changes and only if its not a record record.
I know I can do...
before_save :reset_confirmation, if: :email_changed?
def reset_confirmation
self.confirmed_at = nil
self.confirmation_sent_at = nil
end
and I'm pretty sure this works...
before_save :reset_confirmation, unless: new_record?
def reset_confirmation
self.confirmed_at = nil
self.confirmation_sent_at = nil
end
but how do I combine the two, or is there an easier way to achieve what I want and I'm overthinking things. The field (email) will always contains a value after it's been created if that helps?
Upvotes: 1
Views: 2224
Reputation: 106882
I wonder if the readability and maintainability of the class improve when the callback is replaced by an explicit setter method:
def email=(new_email)
unless new_email == email
self.confirmed_at = nil
self.confirmation_sent_at = nil
write_attribute(:email, new_email)
end
end
Upvotes: 0
Reputation: 41
I went with this in the end...
before_update :reset_confirmation, if: :email_changed?
def reset_confirmation
self.confirmed_at = nil
self.confirmation_sent_at = nil
end
with the logic being that before_update only runs on existing records, which takes care of the new record issue, and now it doesn't step into the method unless the condition has been met to reset the fields anyway.
Upvotes: 0
Reputation: 10497
You can use multiple conditions in your callback, like this:
before_save :reset_confirmation, if: :email_changed?, unless: :new_record?
def reset_confirmation
self.confirmed_at = nil
self.confirmation_sent_at = nil
end
Or, you could add another method to check both conditions, for example:
before_save :reset_confirmation, if: :email_changed_and_its_not_new_record?
def reset_confirmation
self.confirmed_at = nil
self.confirmation_sent_at = nil
end
def email_changed_and_its_not_new_record?
email_changed? && !new_record?
end
You can find more information for conditional callbacks here.
Upvotes: 2