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.