Two Reasons to Use Scopes instead of Class Methods in Rails

Image for post
Image for post

In one of my previous blogs, I explained the difference between Scopes and Class Methods in Rails. In this blog, I will explain two benefits of using Scopes instead of writing them as regular Class Methods.

What happens when you define a scope in Rails

Scopes are just methods that get converted internally by Active Record to Class Methods. For instance, a simplified implementation of ‘A’ student scope would look similar to this after it gets converted to a class method:

def self.a_student
where(grade: 'A')
end

That's why many developers don’t feel the need to write scopes instead of class methods believing that it is just another way or a syntactic sugar to write a class method. However, here are some benefits that you only get if you are using Scopes:

Unlike regular methods, Scopes can be chained to one another. Let’s explain this with an example. Assume you have the following two scopes:

class Student < ActiveRecord::Base
scope :female, -> { where(gender: 'female') }
scope :a_students, -> { where(grade: 'A') }
end

Here, I have two Scopes, female and a_students. One will return all female students and the other will return all ‘A’ students. By having that, I can chain both scopes to get all ‘A’ students that are females.

Student.female.a_students

The nice thing about this is that only one SQL query will be executed. For our female ‘A’ students, Rails will generate only the following SQL query:

SELECT * FROM students WHERE gender = 'female' AND grade = 'A';

What this means is that there will be no unnecessary data fetching from the database until you try to do something with that data. For our previous example, if you do only the following, data will not be loaded:

Student.female.a_students

However, the data is only loaded if you try to do something with it. Like this:

Student.female.a_students.to_a.each do |female_a|
female_a.reward = '$100'
end

Hope that was enough to convince you that using scopes is more efficient in most cases instead of writing usual class methods. If you have anything you would like to add, please comment below.

Written by

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store