Bird
Raised Fist0
Ruby on Railsframework~30 mins

Scopes for reusable queries in Ruby on Rails - Mini Project: Build & Apply

Choose your learning style10 modes available
Scopes for reusable queries
📖 Scenario: You are building a simple blog application where you want to easily find published posts and posts created recently.
🎯 Goal: Create reusable query scopes in the Post model to filter published posts and recent posts.
📋 What You'll Learn
Create a Post model with title, body, published (boolean), and created_at attributes
Add a scope called published that returns only posts where published is true
Add a scope called recent that returns posts created within the last 7 days
Use ActiveRecord query methods to define the scopes
💡 Why This Matters
🌍 Real World
Scopes help keep your Rails code clean and DRY by reusing common queries across your app.
💼 Career
Understanding scopes is essential for Rails developers to write maintainable and efficient database queries.
Progress0 / 4 steps
1
Create the Post model with attributes
Create a Post model class that inherits from ApplicationRecord with attributes title, body, published, and created_at.
Ruby on Rails
Hint

Define the model class and mention the attributes as comments for clarity.

2
Add a scope for published posts
Add a scope called published in the Post model that returns posts where published is true using where(published: true).
Ruby on Rails
Hint

Use scope :published, -> { where(published: true) } to define the scope.

3
Add a scope for recent posts
Add a scope called recent in the Post model that returns posts created within the last 7 days using where('created_at >= ?', 7.days.ago).
Ruby on Rails
Hint

Use scope :recent, -> { where('created_at >= ?', 7.days.ago) } to define the recent posts scope.

4
Use the scopes in a query
Write a query using the Post model that chains the published and recent scopes to get posts that are published and created within the last 7 days.
Ruby on Rails
Hint

Chain the scopes by calling Post.published.recent and assign it to posts.

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