Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Rails 5 uses ApplicationRecord instead of ActiveRecord::Base?

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?

like image 997
Hieu Pham Avatar asked May 21 '16 06:05

Hieu Pham


People also ask

What is ActiveRecord :: Base in Rails?

ActiveRecord::Base indicates that the ActiveRecord class or module has a static inner class called Base that you're extending. Edit: as Mike points out, in this case ActiveRecord is a module... ActiveRecord is defined as a module in Rails, github.com/rails/rails/tree/master/activerecord/lib/…

What is ActiveRecord in Ruby on Rails?

Active Record is the M in MVC - the model - which is the layer of the system responsible for representing business data and logic. Active Record facilitates the creation and use of business objects whose data requires persistent storage to a database.

Is ActiveRecord an ORM?

ActiveRecord is an ORM. It's a layer of Ruby code that runs between your database and your logic code. When you need to make changes to the database, you'll write Ruby code, and then run "migrations" which makes the actual changes to the database.


2 Answers

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 into ActiveRecord::Base and it is present there forever for all later uses of ActiveRecord::Base (it cannot be "unmixed") and there is no way to get the original ActiveRecord::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 of ActiveRecord::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.

like image 148
Matouš Borák Avatar answered Sep 23 '22 12:09

Matouš Borák


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.

like image 37
Jordan Pickwell Avatar answered Sep 22 '22 12:09

Jordan Pickwell