Named Scopes are a subset of a collection. I will illustrate this with an example. If you have Users and you wish to find all users who have their account confirmed. This means you will have some sort of column in your database that represents this. Let's assume that the column is
user_confirmed
. We would query the database without using scopes like this:
User.where(user_confirmed:true)
Using queries like this means that we have to repeat this code everywhere we would like to retrieve all confirmed users.
This does not help us DRY our code. Instead of repeating the same code all the time we could go the scope route as shown below.
#File: user.rb
class User < ActiveRecord::Base
scope :confirmed, ->(){where(user_confirmed: true)}
end
This allows us to get the list of confirmed user like this:
User.confirmed
This is a very simple example. Scopes can be chained to build complex queries. Let's see an example of scope chaining.
In this example, let's say you want a query for a confirmed user with a particular name.
The class file will look like this:
#File: user.rb
class User < ActiveRecord::Base
scope :confirmed, ->(){where(user_confirmed: true)}
scope :name, -> (name) { where(name: name) }
end
The defined scopes above will be chained like this:
User.confirmed.name('Nonso')
Scopes are lazy loaded. This means that the query is not executed until you try to use the result of the query.
For example:
User.confirmed.name('Nonso').upcase
What is the difference between scopes and class methods?
Scopes are used when you do not have extra processing to perform on the retrieved data. If you have to perform some sort of processing then stick to class methods.
I will talk about class methods in my next article.
Scope is a nice utility and helps keep our codes clean readable and simple.