Why Rails 5 uses ApplicationRecord instead of ActiveRecord::Base?
Ruby on-RailsRuby on-Rails-4Ruby on-Rails-5Ruby on-Rails Problem Overview
We know that Rails 5 added ApplicationRecord
as an abstract class which was inherited by our models (ActiveRecord).
But basically, I think every technical requirement we do with ApplicationRecord, we can also do with ActiveRecord::Base
. For instance:
module MyFeatures
def do_something
puts "Doing something"
end
end
class ApplicationRecord < ActiveRecord::Base
include MyFeatures
self.abstract_class = true
end
So now every model will be attached the behaviors of MyFeatures
. But we can also achieve this in Rails 4:
ActiveRecord::Base.include(MyFeatures)
So what is the benefit of using ApplicationRecord
, do you think it is necessary to add ApplicationRecord
?
Ruby on-Rails Solutions
Solution 1 - Ruby on-Rails
While it may seem the same in basic Rails applications, there actually is an important difference once you begin to use rails engines, plugins / gems or direct methods from ActiveRecord::Base
.
-
ActiveRecord::Base.include(MyFeatures)
mixes in the features directly intoActiveRecord::Base
and it is present there forever for all later uses ofActiveRecord::Base
(it cannot be "unmixed") and there is no way to get the originalActiveRecord::Base
anymore in any code after the include. This can easily lead to problems if some of the mixed in feature changed the default ActiveRecord behavior or if e.g. two engines / gems tried to include same-named methods. -
On the other hand, the
ApplicationRecord
approach makes the features present only for the classes (models) that inherit from it, other classes, as well as direct use ofActiveRecord::Base
stay pristine, uncluttered by the module features.
This is especially important when engines or rails plugins are used as it allows them to separate their own model logic from the main application's model logic which was not possible before ApplicationRecord
.
All of this is also nicely described in this blog post and this github comment.
Solution 2 - Ruby on-Rails
This is to expand on @BoraMa's answer, and to, hopefully, clear up some confusion around ActiveRecord::Base.abstract_class
.
ActiveRecord::Base.abstract_class
goes back to at least Rails 3.2.0 (http://api.rubyonrails.org/v3.2.0/classes/ActiveRecord/Inheritance/ClassMethods.html), which was released on January 20, 2012.
Rails 4.0.0 improved the documentation: http://api.rubyonrails.org/v4.0.0/classes/ActiveRecord/Inheritance/ClassMethods.html
So, to everyone who thinks ApplicationRecord
is radically new, it's not. It is an improvement, not a breaking change. Nothing was added to ActiveRecord::Base
to make this work.
I did the same thing on a Rails 4.2.6 project because the models used UUIDs for ids instead of integers, and this required a change to the default ORDER BY
. So, instead of using copy-paste or a concern, I went with inheritance using a UuidModel
class and self.abstract_class = true
.