ruby 14 lines · 1 tab

ActiveRecord scopes for reusable query logic

Alex Kumar Jan 2026
1 tab
class Post < ApplicationRecord
  belongs_to :author, class_name: 'User'
  has_many :comments, dependent: :destroy

  scope :published, -> { where.not(published_at: nil).where('published_at <= ?', Time.current) }
  scope :draft, -> { where(published_at: nil) }
  scope :recent, -> { order(created_at: :desc) }
  scope :by_author, ->(author_id) { where(author_id: author_id) }
  scope :tagged_with, ->(tag) { where('tags @> ARRAY[?]::varchar[]', tag) }

  def published?
    published_at.present? && published_at <= Time.current
  end
end
1 file · ruby Explain with highlit

Scopes encapsulate reusable query logic directly in the model, improving code readability and reducing duplication across controllers and services. I use scopes for common filters like active, published, or recent rather than writing raw where clauses everywhere. The chainable nature of scopes makes it easy to compose complex queries from simple building blocks without introducing SQL injection vulnerabilities. I prefer using lambda syntax for scopes that accept parameters to ensure lazy evaluation. When scopes grow complex, I extract them into dedicated query objects, but for straightforward filters, scopes keep the model layer clean and self-documenting. This pattern also makes testing easier since I can verify query logic in model specs independently.


Related snips

Share this code

Here's the card — post it anywhere.

ActiveRecord scopes for reusable query logic — share card
Link copied