Rails #invert_where - Easy way to invert queries
I was happy to see the introduction of the #not(...)
query method in ActiveRecord. The #invert_where
uses the same mechanics like the `#not(...) and inverts an entire query. This method merged to the Ruby on Rails master branch will be available to us in Rails v7.
It is hard to think of a particular use case, but it is a query that comes in handy now and then. Think about a scenario where I want to list super admins in one column and the others in another. With invert where we can have
Without #invert_where
Without the #invert_where query method will need to write an additional query from scratch to get the result. An additional query may be preferable for a simple query like this, but you will find this very useful for complex queries.
super_admins = User.where(access_level: 0)
other_users = User.where.not(access_level: 0)
The generated SQL for the where.not(...)
would be in the line:
SELECT "users".* FROM "users" WHERE ("users"."access_level" != 0)
With #invert_where
The #invert_where
allows us to invert an existing query. It uses a SQL NOT
.
super_admins = User.where(access_level: 0)
other_users = super_adins.invert_where
The generated SQL for the invert_where
would use the NOT
as follows:
SELECT "users".* FROM "users" WHERE NOT ("users"."access_level" = 0)
Aren't they different?
They may look different, but they are not. Check out De Morgan's Laws (specifically the law about intersection).
Conclusion
The invert_where
query method will surely be helpful when it finally becomes available with Rails 7. But then again, it is not a big deal but something to make our lives easy.
About the Author
Ziyan Junaideen -
Ziyan is an expert Ruby on Rails web developer with 8 years of experience specializing in SaaS applications. He spends his free time he writes blogs, drawing on his iPad, shoots photos.