DEV Community

loading...

How to use Scopes in Ruby on Rails

justalever profile image Andy Leverenz Originally published at web-crunch.com on ・2 min read

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Creating new records

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

Post.status.new.published #=> true
Enter fullscreen mode Exit fullscreen mode

Further reading

Looking for more Ruby on Rails content?

Check out my collections dedicated to the framework:

Discussion (0)

pic
Editor guide