We write about Ruby on Rails, React.js, React Native, remote work, open source, engineering and design.
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.