Yay Rails will change the behavior of the ActiveRecord#not on rails
6.1. That’s great as the current behavior sometimes leads to confusion. There will be a deprecation message on the version
6.0 so let’s watch out and change our code accordingly.
As I already wrote on this TIL this function does not act as a legit boolean algebra negation. Let’s say that we have this query:
User.where.not(active: true, admin: true).to_sql
Prior to this change this will produce this query:
SELECT users.* FROM users WHERE users.active != 't' AND users.admin != 't'
The problem is that negating an AND clause is naturally a NAND operator, but Rails have implemented as a NOR. Some developers might wonder why regular active users are not returning.
On Rails 6.1 this will be fixed hence the new query will be:
SELECT users.* FROM users WHERE users.active != 't' OR users.admin != 't'
Here’s the rollout plan:
5.2.3acts as NOR
6.0.0acts as NOR with a deprecation message
6.1.0act as NAND
This is the PR in case you want to know more.Tweet