Don't Forget the Return Value on Rails Callbacks
This morning I spent a good while hashing on a problem in some new code I’m updating for a freelance project. I added a couple callbacks to an ActiveRecord model, and things that previously worked were broken. Unfortunately there were no errors in the model or exceptions in the system to give me a hint as to what went wrong. When I finally uncovered the problem, I was thankful that it was something I had never run into before.
That being said, I sure don’t want to make the mistake again. The offending code looked similar to this:
before_save :update_show_on_navigation
private
def update_show_on_navigation
if !self.navigation.blank?
self.navigation.show_on_nav = self.published? # If published, show on nav
end
end
What’s going on here? Why was my model not saving successfully and also providing no errors or exceptions? The section “cancelling callbacks” in the callbacks documentation gave me my answer:
If a before_* callback returns false, all the later callbacks and the associated action are cancelled.
Oh boy! Sure enough, that code above could easily resolve to “false” if the model is not “published”. To be sure that the action I’m targeting (save) isn’t cancelled, I simply return “true” at the end of the method.
before_save :update_show_on_navigation
private
def update_show_on_navigation
if !self.navigation.blank?
self.navigation.show_on_nav = self.published? # If published, show on nav
end
true
end