0
0
RailsHow-ToBeginner · 3 min read

How to Chain Scopes in Rails: Syntax and Examples

In Rails, you can chain scopes by calling multiple scope methods one after another on an ActiveRecord model. Each scope returns a relation, allowing you to combine conditions like Model.scope1.scope2 to build complex queries cleanly.
📐

Syntax

Scopes in Rails are defined as class methods returning an ActiveRecord::Relation. You chain scopes by calling them one after another on a model, each narrowing down the query.

  • scope :name, -> { where(condition) } defines a scope.
  • Chaining example: Model.scope1.scope2 applies both conditions.
  • Each scope returns a relation, so chaining combines them with AND logic.
ruby
class Product < ApplicationRecord
  scope :available, -> { where(available: true) }
  scope :priced_over, ->(amount) { where('price > ?', amount) }
end

# Chaining scopes
Product.available.priced_over(100)
Output
Returns all products where available is true AND price is greater than 100
💻

Example

This example shows how to define two scopes and chain them to filter products that are available and cost more than a given price.

ruby
class Product < ApplicationRecord
  scope :available, -> { where(available: true) }
  scope :priced_over, ->(amount) { where('price > ?', amount) }
end

# Usage in Rails console or controller
products = Product.available.priced_over(50)
products.each do |product|
  puts "#{product.name} - $#{product.price}"
end
Output
Outputs product names and prices for products that are available and priced over 50
⚠️

Common Pitfalls

Common mistakes when chaining scopes include:

  • Defining scopes that do not return a relation, breaking the chain.
  • Using scopes that execute queries immediately instead of returning relations.
  • Forgetting to pass parameters correctly in scopes.

Always ensure scopes return an ActiveRecord::Relation to keep chaining possible.

ruby
class Product < ApplicationRecord
  # Wrong: returns array, breaks chaining
  scope :wrong_scope, -> { all.to_a }

  # Right: returns relation
  scope :correct_scope, -> { all }
end

# Wrong chaining example (raises error)
# Product.wrong_scope.available

# Correct chaining example
Product.correct_scope.available
Output
The wrong_scope breaks chaining because it returns an array, while correct_scope allows chaining
📊

Quick Reference

ConceptDescriptionExample
Define scopeCreate reusable query partsscope :active, -> { where(active: true) }
Chain scopesCombine multiple scopesModel.active.recent
Return relationScopes must return ActiveRecord::Relationscope :recent, -> { order(created_at: :desc) }
Pass parametersScopes can accept argumentsscope :priced_over, ->(price) { where('price > ?', price) }

Key Takeaways

Scopes return ActiveRecord::Relation objects that can be chained to build complex queries.
Always define scopes to return relations, not arrays or other objects.
Chain scopes by calling them one after another on the model, e.g., Model.scope1.scope2.
Scopes can accept parameters to make queries dynamic and reusable.
Chaining scopes combines their conditions with AND logic in the final query.