Reputation: 1234
I'm trying to rewhere
or unscope
a query, where the original condition cannot be written using hash condition:
Reservation.where('block_id IS NULL OR block_id != ?', 'something')
> SELECT `reservations`.* FROM `reservations` WHERE (block_id IS NULL OR block_id != 'something')
Trying to rewhere doesn't work:
Reservation.where('block_id IS NULL OR block_id != ?', 'something').rewhere(block_id: 'anything')
> SELECT `reservations`.* FROM `reservations` WHERE (block_id IS NULL OR block_id != 'something') AND `reservations`.`block_id` = 'anything'
But this example with hash condition
would work:
Reservation.where.not(block_id: 'something').rewhere(block_id: 'anything')
> SELECT `reservations`.* FROM `reservations` WHERE `reservations`.`block_id` = 'anything'
I understand that this is probably because on the array condition
rails doesn't know which column I'm invoking a where, and therefore rewhere
won't find anything to replace.
Is there any way to explicitly tell which column I'm filtering in an array condition? or rewrite the first query (IS NULL OR != value) with hash condition?
Note: Please don't suggest unscoped
, as I'm trying to unscope/rewhere only this specific condition, not the whole query.
Thanks!
Upvotes: 3
Views: 1026
Reputation: 1352
Sorry it wasn't clear that you had other where clauses that you wanted to keep. You could access the array of where clauses using relations.values[:where]
and manipulate it, something like:
Reservation.where('block_id IS NULL OR block_id != ?', 'something')
.tap do |relation|
# Depending on your version of Rails you can do
where_values = relation.where_values
# Or
where_values = relation.values[:where]
# With the first probably being better
where_values.delete_if { |where| ... }
end
.where(block_id: 'anything')
aka hacking
Upvotes: 3