Bird
Raised Fist0
Ruby on Railsframework~10 mins

Scopes for reusable queries in Ruby on Rails - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Scopes for reusable queries
Define Scope Method
↓
Call Scope on Model
↓
Scope Returns Relation
↓
Chain or Execute Query
↓
Get Filtered Results
Scopes are methods defined in a model that return filtered queries. You call them to get reusable, chainable query parts.
Execution Sample
Ruby on Rails
class Product < ApplicationRecord
  scope :available, -> { where(available: true) }
end

Product.available
Defines a scope named 'available' that filters products where available is true, then calls it.
Execution Table
StepActionEvaluationResult
1Define scope :availablescope :available, -> { where(available: true) }Scope method added to Product
2Call Product.availableProduct.availableReturns ActiveRecord::Relation with where(available: true)
3Execute queryProduct.available.to_aArray of products with available = true
4Chain scopes (if any)Product.available.other_scopeCombined query with both filters
5EndNo more callsQuery ready for use or execution
💡 Scopes return relations until executed; execution fetches filtered records.
Variable Tracker
VariableStartAfter 1After 2Final
Product.availableundefinedActiveRecord::Relation (where available: true)Same relationArray of filtered products after execution
Key Moments - 2 Insights
Why does calling Product.available not immediately fetch records?
Because scopes return a relation object that builds the query but delays execution until needed, as shown in execution_table step 2 and 3.
Can scopes be chained together?
Yes, scopes return relations that can be chained to combine filters, as shown in execution_table step 4.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, what does Product.available return at step 2?
AAn array of products
BAn ActiveRecord::Relation with a where clause
CA boolean value
DA SQL string
💡 Hint
Check the 'Evaluation' and 'Result' columns at step 2 in the execution_table.
At which step does the query actually fetch records from the database?
AStep 1
BStep 2
CStep 3
DStep 4
💡 Hint
Look for when the relation is converted to an array in the execution_table.
If you chain another scope after Product.available, what happens to the query?
AIt combines filters into one query
BIt executes the query immediately
CIt replaces the previous scope
DIt causes an error
💡 Hint
See step 4 in the execution_table about chaining scopes.
Concept Snapshot
Scopes are reusable query methods in Rails models.
Define with scope :name, -> { query }.
Calling a scope returns a relation, not records.
Scopes can be chained to combine filters.
Query runs when you fetch records (e.g., to_a, each).
Full Transcript
In Rails, scopes let you write reusable query parts inside your model. You define a scope with a name and a lambda that returns a filtered query. When you call the scope, it returns an ActiveRecord relation object, which builds the query but does not run it yet. You can chain multiple scopes to combine filters. The actual database query runs only when you fetch records, like converting to an array or iterating. This makes your code cleaner and queries reusable.

Practice

(1/5)
1. What is the main purpose of using scopes in a Rails model?
easy
A. To define database table columns
B. To write controller actions
C. To create new database tables
D. To reuse common database queries easily

Solution

  1. Step 1: Understand what scopes do

    Scopes are defined in models to encapsulate common queries for reuse.
  2. Step 2: Identify the correct purpose

    They help avoid repeating query code by providing reusable query methods.
  3. Final Answer:

    To reuse common database queries easily -> Option D
  4. Quick Check:

    Scopes = reusable queries [OK]
Hint: Scopes are for reusable queries inside models [OK]
Common Mistakes:
  • Confusing scopes with database schema definitions
  • Thinking scopes create tables or columns
  • Mixing scopes with controller logic
2. Which of the following is the correct syntax to define a scope named active that selects records with status: 'active'?
easy
A. scope :active, -> { where(status: 'active') }
B. scope active: where(status: 'active')
C. def scope :active; where(status: 'active'); end
D. scope :active { where(status: 'active') }

Solution

  1. Step 1: Recall scope syntax

    Scopes use the syntax: scope :name, -> { query }.
  2. Step 2: Match the correct option

    scope :active, -> { where(status: 'active') } matches this syntax exactly with a lambda returning the query.
  3. Final Answer:

    scope :active, -> { where(status: 'active') } -> Option A
  4. Quick Check:

    Scope syntax = scope :name, -> { ... } [OK]
Hint: Use lambda with -> { ... } for scope queries [OK]
Common Mistakes:
  • Omitting the lambda syntax -> { ... }
  • Using incorrect method definitions for scopes
  • Missing colon before scope name
3. Given the following scopes in a Rails model:
scope :published, -> { where(published: true) }
scope :recent, -> { order(created_at: :desc) }

What will Article.published.recent.to_sql return?
medium
A. SELECT * FROM "articles" WHERE "articles"."published" = FALSE ORDER BY "articles"."created_at" ASC
B. SELECT * FROM "articles" ORDER BY "articles"."created_at" DESC WHERE "articles"."published" = TRUE
C. SELECT * FROM "articles" WHERE "articles"."published" = TRUE ORDER BY "articles"."created_at" DESC
D. SELECT * FROM "articles" WHERE "articles"."published" = TRUE

Solution

  1. Step 1: Understand scope chaining

    Chaining scopes combines their queries in order: published adds a WHERE clause, recent adds ORDER BY.
  2. Step 2: Analyze the SQL generated

    The SQL will filter published = true and order by created_at descending.
  3. Final Answer:

    SELECT * FROM "articles" WHERE "articles"."published" = TRUE ORDER BY "articles"."created_at" DESC -> Option C
  4. Quick Check:

    Chained scopes combine WHERE and ORDER BY [OK]
Hint: Chained scopes combine queries in order [OK]
Common Mistakes:
  • Placing ORDER BY before WHERE in SQL
  • Confusing true/false values in conditions
  • Ignoring scope chaining order
4. Identify the error in this scope definition:
scope :recent, { order(created_at: :desc) }
medium
A. Missing lambda syntax -> { ... } around the query
B. Incorrect scope name format
C. Using order instead of where
D. Scope must be defined in controller, not model

Solution

  1. Step 1: Check scope syntax requirements

    Scopes require a lambda (-> { ... }) to wrap the query for lazy evaluation.
  2. Step 2: Identify missing lambda

    The given scope uses curly braces without the lambda arrow, causing a syntax error.
  3. Final Answer:

    Missing lambda syntax -> { ... } around the query -> Option A
  4. Quick Check:

    Scopes need -> { ... } [OK]
Hint: Always wrap scope queries in -> { ... } [OK]
Common Mistakes:
  • Omitting the lambda arrow ->
  • Defining scopes outside models
  • Confusing order and where methods
5. You want to create a scope recent_active that returns records which are both active: true and created in the last 7 days. Which is the correct way to define this scope?
hard
A. scope :recent_active, -> { where(active: true).order('created_at >= 7.days.ago') }
B. scope :recent_active, -> { where(active: true).where('created_at >= ?', 7.days.ago) }
C. scope :recent_active, -> { where(active: true && created_at >= 7.days.ago) }
D. scope :recent_active, -> { where(active: true).where(created_at: 7.days.ago) }

Solution

  1. Step 1: Combine conditions with where

    Use chained where calls to combine multiple conditions logically ANDed.
  2. Step 2: Use correct date comparison syntax

    Use a SQL fragment with placeholder and 7.days.ago to compare dates properly.
  3. Final Answer:

    scope :recent_active, -> { where(active: true).where('created_at >= ?', 7.days.ago) } -> Option B
  4. Quick Check:

    Chain where with SQL and placeholders [OK]
Hint: Chain where with SQL and placeholders for complex conditions [OK]
Common Mistakes:
  • Using && inside where hash instead of chaining
  • Using order for filtering conditions
  • Comparing created_at with exact date instead of range
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard