Blog

Thoughts from my daily grind

Rails #invert_where - Easy way to invert queries

Posted by Ziyan Junaideen |Published: 29 May 2021 |Category: Ruby on Rails
Default Upload |

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.

Comments