Rails 7
adds
ability to pass all_queries: true
option to the ActiveRecord #scoping
method.
The passed option will create a global scope that gets applied to all queries for the duration of the block.
Before
Let’s say we have an Article
model which belongs to the User
.
Scoping method only worked on class queries (Article.create, Article.all, Article.update_all) and not on class objects (article.update or article.delete).
We can check this in the below example:
In the above SQL query, we can see that scope articles.user_id
is being applied to the update_all
query.
But in case of article
update, this scope is missing.
After
To fix the above issue, Rails 7 allows us to pass all_queries: true
to the scoping method.
We can see that scope articles.user_id
is now applied to the update query inside the
scoping block.
Limitations
Scoping only applies to the objects of the same class
Let’s take an example to understand it better.
Suppose we have a Category
model which belongs to Article
.
In the above example scope, articles.user_id = 1
is missing in the generated SQL query.
This is because the scope is applied to the Article model and not on Category.
If a block is scoped to all_queries, it cannot be unscoped inside the same block
When we try to pass option all_queries: false
, inside a block that already
has all_queries: true
, it will throw an ArgumentError
.