rewhere
Interesting problem requiring us to remove the where values on an ActiveRecord::Relation. The original heavy handed method seems to play havoc with chained where calls and the id of the original proxy_association.owner would get used in a later where. Here we can see that our for_me method seems to cause the else_id to be the same as our recipient_id
[5] pry(#<RSpec::Core::ExampleGroup::Nested_1::Nested_7::Nested_1>)> user.somethings.where(else_id: something.else_id).to_sql
=> "SELECT `somethings`.* FROM `somethings` WHERE `somethings`.`user_id` = 20323 AND `somethings`.`else_id` = 6465 ORDER BY id DESC"
[6] pry(#<RSpec::Core::ExampleGroup::Nested_1::Nested_7::Nested_1>)> user.somethings.for_me.where(else_id: something.else_id).to_sql
=> "SELECT `somethings`.* FROM `somethings` WHERE `somethings`.`recipient_id` = 20323 AND `somethings`.`else_id` = 20323 ORDER BY id DESC
when in doubt read the Rails source
# remove user_id = proxy_association.owner.id from scope
# so it can be reapplied by to_me or for_me
def global_scope
- s = respond_to?(:scoped) ? scoped : all
- s.where_values = []
- s
+ unscope(where: :user_id)
end
which is the way that rewhere reassigns values in where rather than chaining again
2.2.2 :006 > Something.where(user_id: 1).where(user_id: 2).to_sql
=> "SELECT `somethings`.* FROM `somethings` WHERE `somethings`.`user_id` = 1 AND `somethings`.`user_id` = 2"
2.2.2 :007 > Something.where(user_id: 1).rewhere(user_id: 2).to_sql
=> "SELECT `somethings`.* FROM `somethings` WHERE `somethings`.`user_id` = 2"