We have been working to move from 2.3.3 to 3.0.0.beta4 recently
and have run into this decision:
Base#before_save has been deprecated, please use Base.before_save :method instead. (called from <class:User> at app/models/user.rb
I assume this decision was designed to protect people from
themselves; that is, where they use inheritance or mixins that
result in multiple "def before_save" definitions, which results in
them not getting the callbacks that they expect. So the Rails team
is recommending that the other ways of registering callbacks are
preferred.
IF so, this is just that - a recommendation - and should remain
as such. It's a great thing to document and point out to people as
a caveat. It's also a great thing for plugin others to abide by.
However, the "def before_save" idiom has been in Rails for years,
and is immensely powerful. Consider:
class Auto < ActiveRecord::Base
def before_save
# ...
end
end
class Car < Auto
def before_save
super
# ...
end
end
The great thing about this approach is the developer is using
features of the Ruby language. A while ago Yehuda posted a long
blog post about how we need to go back to our Ruby roots, and this
approach supports that.
Furthermore, you can get into just as much trouble with the
symbol approach:
class Auto < ActiveRecord::Base
before_save :set_defaults
def set_defaults
# ...
end
end
class Car < Auto
before_save :set_defaults
def set_defaults
# ...
end
end
With this setup, the developer could mistakenly think both were
going to get called; using the symbol method name approach obscures
what is going on under the hood. You would still need to put
"super" in set_defaults, which requires a good amount of
explanation.
Please reverse this decision and allow us Rails users to keep
the "def callback" approach which has proven to be so powerful in
Rails over the past years.
Thanks,
Nate Wiger
PlayStation