Scopes in RoR

John DeWolf
2 min readJan 18, 2014

--

TIL scopes can be an extremely useful tool to implement in your code.

I kept reading and hearing about using scopes in a rails app. I wasn’t quite sure what they were, all I knew was that the term ‘scope’ sounded pretty badass. I was running into issues in my views when I was trying to display groups of a class. For example, in my current project I have ‘goals’ and goals can be active or inactive depending on their attributes. I found myself writing blocks like the following

<% @user.goals.each do |goal| %><% if goal.completed? != true && goal.end_date > Date.today %>

This was getting extremely tedious to do each time I wanted to display a group of goals, such as completed, past, incomplete, or active goals. It also made the code in my views completely illegible and nearly impossible to follow.

The solution for this was to create a scope in the Goal class. A scope is a saved sequel query that returns an Active Record relation object, which can essentially be treated like an array.

I replaced that previous block with the following two scopes:

def self.incomplete

 def self.incomplete   where(completed_on: nil) end def self.active   incomplete.where("end_date >= ?", Date.today) end

Here, two scopes are chained together. The first returns all the records that don’t have the “completed_on” field filled out. The second uses that scope, to further narrow it down to only the records who have an end date in the future.

Besides cleaning up the code, this is also much more efficient to run. Instead of looping through the whole table and keeping each goal in it’s memory, it utilizes a SQL query. Although I may not see much of a difference in my small app that I am testing with ten records in the database, it would have a huge impact if there were a lot of records and makes the app much more scalable.

I can now call this scope on the goals for a specific user. For example I can do “user.goals.active” and the scope will adjust for only the goals that belong to the user.

--

--