Rails 6.1 allows default_scope to be run on all queries

Unnikrishnan KP

By Unnikrishnan KP

on December 29, 2020

This blog is part of our  Rails 6.1 series.

Before Rails 6.1 if a default_scope was defined in a model it would be applied only for select and insert queries. Rails 6.1 adds an option all_queries: true that could be passed to default_scope to make the scope applicable for all queries.

1default_scope -> { where(...) }, all_queries: true

Consider the Article class below.

1class Article
2  default_scope -> { where(organization_id: Current.organization_id) }
3end
4
5@article.update title: "Hello World"
6@article.delete

The update and delete methods would generate SQL queries as shown below. As we can see that default_scope is missing from these queries.

1UPDATE "articles" SET "title" = $1 WHERE "articles"."id" = $2 [["title", "Hello World"], ["id", 146]]
2
3DELETE FROM "articles" WHERE "articles"."id" = $1  [["id", 146]]

In Rails 6.1 we can solve this problem by passing all_queries: true to the default_scope.

1class Article
2  default_scope -> { where(organization_id: Current.organization_id) }, all_queries: true
3end

Then the generated SQL changes to this:

1UPDATE "articles" SET "title" = $1 WHERE "articles"."id" = $2 AND "articles"."organization_id" = $3  [["title", "Hello World"], ["id", 146], ["organization_id", 314]]
2
3DELETE FROM "articles" WHERE "articles"."id" = $1 AND "articles"."organization_id" = $2  [["id", 146], ["organization_id", 314]]

Ability to make default_scopes applicable to all queries is particularly useful in the case of multi-tenanted applications, where an organization_id or repository_id is added to the tables to support sharding.

Check out the pull request for more details on this feature.