Seb's blog

How to unscope nested where conditions in Rails

If your query doesn't have nested hashes in the where condition, then it's simple as something like this;

User.where(name: 'John').unscope(where: :name)

If you do have a nested hash like;

User
  .left_joins(:posts)
  .where(posts: { id: nil })

then you need to use every key from the hash used as the where parameters (the condition value is omitted);

User
  .left_joins(:posts)
  .where(posts: { id: nil })
  .unscope(where: { posts: :id })

The same applies to negative conditions (where.not);

User
  .left_joins(:posts)
  .where.not(posts: { id: 1 })
  .unscope(where: { posts: :id })

You might also be tempted to use rewhere, but that won't work in this case, as you can not rewhere with a negative condition. That's to say you can do this;

User
  .left_joins(:posts)
  .where.not(posts: { id: nil })
  .rewhere(posts: { id: nil }) # going from IS NOT NULL to IS NULL

but you can not do this;

User
  .left_joins(:posts)
  .where(posts: { id: nil })
  .rewhere.not(posts: { id: nil }) # that's just a silly attempt

And if you try to use unscoped then you'll remove any condition, join, group by, etc from the query itself;

User
  .left_joins(:posts)
  .where(posts: { id: nil })
  .unscoped
# => SELECT "users".* FROM "users"

And also, you cannot unscope where condition passed as string arguments;

User
  .left_joins(:posts)
  .where('posts.title LIKE ?', '%My beautiful post%')
  .unscope(where: { posts: :title })