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.
default_scope -> { where(...) }, all_queries: true
Consider the Article class below.
class Article
default_scope -> { where(organization_id: Current.organization_id) }
end
@article.update title: "Hello World"
@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.
UPDATE "articles" SET "title" = $1 WHERE "articles"."id" = $2 [["title", "Hello World"], ["id", 146]]
DELETE 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
.
class Article
default_scope -> { where(organization_id: Current.organization_id) }, all_queries: true
end
Then the generated SQL changes to this:
UPDATE "articles" SET "title" = $1 WHERE "articles"."id" = $2 AND "articles"."organization_id" = $3 [["title", "Hello World"], ["id", 146], ["organization_id", 314]]
DELETE 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.
If this blog was helpful, check out our full blog archive.