Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How was ActiveRecord "none" method implemented with NullRelation?

I am trying to understand the none method introduced in Rails4.

Here is the implementation from Rails API

def none
  where("1=0").extending!(NullRelation)
end

And I found similar implementation here in Rails3 way.

scope :none, where(:id => nil).where("id IS NOT ?", nil)

Can anyone help me understand how this method was implemented with NullRelation in Rails4 and advantages?

like image 650
Venkat Ch Avatar asked Jul 23 '15 07:07

Venkat Ch


People also ask

Is ActiveRecord an ORM?

ActiveRecord is an ORM. It's a layer of Ruby code that runs between your database and your logic code.

Is ActiveRecord a framework?

1.3 Active Record as an ORM Framework Active Record gives us several mechanisms, the most important being the ability to: Represent models and their data. Represent associations between these models. Represent inheritance hierarchies through related models.

What does ActiveRecord base do?

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...

What is an ActiveRecord scope?

Scopes are used to assign complex ActiveRecord queries into customized methods using Ruby on Rails. Inside your models, you can define a scope as a new method that returns a lambda function for calling queries you're probably used to using inside your controllers.


1 Answers

Let's first check ActiveRecord::NullRelation

They basically set to constant values all methods, so whatever you are going to use, won't hit the database.

Remember that when you chain methods over a relation you get a new relation every time, which means, once you hit none, all future methods will try to build a relation from that one. It's easy to imagine that they won't find anything in the database and will just keep returning self (the NullRelation).

In addition, considering that you already linked the current implementation, is pretty clear that they will keep returning an ActiveRecord::Relation, but obviously it won't find anything due to the '1=0' approach. The key point however is in the extending! method, which will overwrite the methods for ActiveRecord::Relation instance (not for all relations, so that's like a singleton instance in Ruby) by forcing it not to hit the database (the exec_queries is replaced with a simple empty array as return value).

like image 185
Francesco Belladonna Avatar answered Oct 13 '22 00:10

Francesco Belladonna