Andy from Webcrunch

Subscribe for email updates:

Portrait of Andy Leverenz
Andy Leverenz

February 4, 2021

Last updated November 5, 2023

How to use Scopes in Ruby on Rails

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.

A use case for scopes is often for filtering by status, date, date ranges, ordering, groupings, and more. ActiveRecord already makes it quite easy to return rich data from your database. Combining those superpowers with scopes allow you to define more memorable queries that you and your team can harness through your Ruby on Rails application.

Here's a quick example of setting status on a Post class. As an example, let's assume we're creating a basic blog and we want some posts to be drafts while others are published. We can assign a status to each post which signifies this.

Examples

class Post < ApplicationRecord
  scope :published, -> { where(status: "Published") }
end

Then in our controller or views, we can return the newly scoped objects.

class PostsController < ApplicationController
  def index
      # only returns those Post objects that have a "Published" status
      @posts = Post.published
  end
end

More complex queries can be performed in the same manner.


class Post < ApplicationRecord
  scope :past_week, -> { where(created_at: Time.zone.now.at_beginning_of_week...Time.zone.now.at_end_of_week) }
end

This returns everything that was created for the current week.

Chaining

Scopes are extremely powerful due to their ability to be chained together. Think of them as chain links. Keep in mind Scopes should only ever be written to be chained.

class PostsController < ApplicationController
  def index
    # returns all published posts for the current week
    @posts = Post.published.past_week
  end
end

Creating new records

Scopes can also be used while creating/building a record.

Post.status.new.published #=> true

Further reading

Looking for more Ruby on Rails content?

Check out my collections dedicated to the framework:

Link this article
Est. reading time: 2 minutes
Stats: 12,929 views

Categories

Collection

Part of the Ruby on Rails collection