Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return an empty ActiveRecord relation?

People also ask

What is ActiveRecord relation?

The Relation Class. Having queries return an ActiveRecord::Relation object allows us to chain queries together and this Relation class is at the heart of the new query syntax. Let's take a look at this class by searching through the ActiveRecord source code for a file called relation.

What does ActiveRecord base mean?

ActiveRecord::Base indicates that the ActiveRecord class or module has a static inner class called Base that you're extending.

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.


There is a now a "correct" mechanism in Rails 4:

>> Model.none 
=> #<ActiveRecord::Relation []>

A more portable solution that doesn't require an "id" column and doesn't assume there won't be a row with an id of 0:

scope :none, where("1 = 0")

I'm still looking for a more "correct" way.


Coming in Rails 4

In Rails 4, a chainable ActiveRecord::NullRelation will be returned from calls like Post.none.

Neither it, nor chained methods, will generate queries to the database.

According to the comments:

The returned ActiveRecord::NullRelation inherits from Relation and implements the Null Object pattern. It is an object with defined null behavior and always returns an empty array of records without quering the database.

See the source code.


You can add a scope called "none":

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

That will give you an empty ActiveRecord::Relation

You could also add it to ActiveRecord::Base in an initializer (if you want):

class ActiveRecord::Base
 def self.none
   where(arel_table[:id].eq(nil).and(arel_table[:id].not_eq(nil)))
 end
end

Plenty of ways to get something like this, but certainly not the best thing to keep in a code base. I have used the scope :none when refactoring and finding that I need to guarantee an empty ActiveRecord::Relation for a short time.


scope :none, limit(0)

Is a dangerous solution because your scope might be chained upon.

User.none.first

will return the first user. It's safer to use

scope :none, where('1 = 0')