Rails Gotcha With before_validation
factore.ca
factore.ca
See the section "Cancelling Callbacks" in the docs for ActiveRecord::Callback: http://rails.rubyonrails.org/classes/ActiveRecord/Callbacks....
"If a before_* callback returns false, all the later callbacks and the associated action are cancelled. If an after_* callback returns false, all the later callbacks are cancelled. Callbacks are generally run in the order they are defined, with the exception of callbacks defined as methods on the model, which are called last."
before_filter in controllers used to work the same way, but somewhere along the way it was changed to check #performed? on the controller. That way before_filters only cancel the action if it redirects or renders a template.
How else would you do that for callbacks though? Force the user to raise something like ActiveRecord::CancelCallback? Use the obscure throw/catch statements?
In practice, maybe a Ruby linter could/should pick this pattern up and warn about it? It wouldn't be hard to identify functions which return a value based on a block if with no else say.
[1] http://www.gigamonkeys.com/book/beyond-exception-handling-co...
I'd rather pay the price of typing
return self.shipping = false
to make the function return false if I actually wanted it to do so, rather than self.shipping = false
true
which just looks bizarre to me and doesn't make its motive clear (you wind up only including it when your last expression evaluates to false). I have vague, unpleasant memories of also encountering this gotcha with Perl in RT scrips, where you would suffix silly little 1;'s and 0;'s to everything to make the next action run or not run.I don't know about everybody else, but I don't FP to the extent that I never write subprocedures. Isn't this still typical?