default_scope code

Don’t use default_scope. Ever.

When you would like a scope to be applied across all queries on a model, you can use default_scope. See more in the ActiveRecord Query Guide and Rails docs.

RailsConf 2024

I'm co-chairing RailsConf 2024 in Detroit May 7–9. Come and join us 


Where you have a blog system with posts that can be set to be hidden, for when you are writing a draft.

Instead of…

default_scope.

# app/models/post.rb
class Post < ActiveRecord::Base
  default_scope { where(hidden: false) }
end

Use…

…explicit scopes.

# app/models/post.rb
class Post < ActiveRecord::Base
  scope, :published -> { where(hidden: false) }
end

…then you can do…

Post.published

But why?

Two reasons. Both to do with avoiding later confusion and bug hunting.

Adding a default scope affects your model initialization. In the example, Post.new is defaulted to hidden = false whether you are expecting it or not.

Trying not to use your defined default scope is a pain. To remove the default_scope when you don’t need it you have to use the unscoped scope (!) which removes all applied conditions including associations.

i.e. Post.first.comments.unscoped would return every comment in your database, not just those for the first Post.

The explicit use of named scopes is a clearer solution. Using default_scope will lead to many hours of bug hunting. Don’t do it to yourself.

Where might I use it?

Seriously. Trust me on this one. It will bite you.

Brighton Ruby 2024

Still running UK’s friendliest, Ruby event on Friday 28th June. Ice cream + Ruby 


Last updated on October 1st, 2017 by @andycroll

An email newsletter, with one Ruby/Rails technique delivered with a ‘why?’ and a ‘how?’ every two weeks. It’s deliberately brief, focussed & opinionated.