Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby on Rails ActiveRecord scopes vs class methods

Tags:

Rails internally converts scopes to class methods then why can't we use class methods itself instead of going with scopes.

like image 661
Subhash Chandra Avatar asked Oct 04 '15 05:10

Subhash Chandra


People also ask

What is the difference between scope and class method Rails?

Scopes are just class methods. Internally Active Record converts a scope into a class method. "There is no difference between them" or “it is a matter of taste”.

What are scope methods Rails?

Scope methods in Rails are special class methods enabled by the ActiveRecord query interface, which allows the programmer to write SQL queries without delving into full SQL.

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.

What is scope in Ruby on Rails?

Scopes are custom queries that you define inside your Rails models with the scope method. Every scope takes two arguments: A name, which you use to call this scope in your code. A lambda, which implements the query. Example: scope :active_users, -> { where(active: true) }


2 Answers

From the fine guide:

14 Scopes
[...]
To define a simple scope, we use the scope method inside the class, passing the query that we'd like to run when this scope is called:

class Article < ActiveRecord::Base
  scope :published, -> { where(published: true) }
end

This is exactly the same as defining a class method, and which you use is a matter of personal preference:

class Article < ActiveRecord::Base
  def self.published
    where(published: true)
  end
end

Note in particular:

This is exactly the same as defining a class method, and which you use is a matter of personal preference

And a little further (the Rails3 guide says the same thing here BTW):

14.1 Passing in arguments
[...]
Using a class method is the preferred way to accept arguments for scopes.

So which you use is a matter of preference and it is even recommended that you use class methods for scopes that take arguments.

Using scope is mostly a notational issue. If you say scope :whatever then you're explicitly saying that whatever is meant to be a query builder; if you say def self.whatever then you're not implying anything about the intent of the whatever method, you're just defining some class method that may or may not behave like a scope.

Of course, 14.1 makes a mess of this notational distinction by recommending that you not use scope when your scope takes arguments. Also keep in mind that in Rails3 you could say:

scope :published, where(published: true)

so an argumentless scope was visually "clean" and terse but adding a lambda to handle arguments would make it look messier:

scope :pancakes, ->(x) { where(things: x) }

But Rails4 wants lambdas even for argumentless scopes the distinction makes even less sense now.

I suspect that the difference is historical at this point. Scopes were probably something special back in the before times but became plain old class methods in the Rails3 era to cut down on duplication and to better mesh with the new query interface that came with Rails3.


So you can skip scope and go straight to class methods if you wish. You're even encouraged to do so when your scope takes arguments.

like image 170
mu is too short Avatar answered Sep 27 '22 18:09

mu is too short


Scopes are just class methods. Internally Active Record converts a scope into a class method.

"There is no difference between them" or “it is a matter of taste”. I tend to agree with both sentences, but I’d like to show some slight differences that exist between both. This blogs explains the difference very well.

like image 37
Somesh Sharma Avatar answered Sep 27 '22 18:09

Somesh Sharma