I was able to reproduce it. This happens when using field "names" that are actually aliases (id → _id and custom ones.)
Trying to identify the code that produced it, I traced it down to Mergeable:
def with_strategy(strategy, criterion, operator)
selection(criterion) do |selector, field, value|
selector.store(
field,
selector[field].send(strategy, prepare(field, operator, value))
)
end
end
Now, it tries to perform Selector#[] with alias, not actual field name, so it gets nil, instead of selector for the real field. So it just uses the new selector. Selector#store does respect aliases, however, so it overrides the existing selector with the new one. (Selector is a subclass of Smash.)
There are actually two ways to fix this, in my opinion:
Make Mergeable#with_strategy try to resolve real field name itself and fetch appropriate selector for field.
Make Selector#[] ( Smash#[]) actually respect aliases that it was instantiated with.
I don't think Mergeable#with_strategy should care about actual field names at this point so I opted for the second way.
TL;DR Origin doesn't merge selectors for aliases properly and this PR fixes that.
I have just encountered this question on StackOverflow: http://stackoverflow.com/questions/16522040/intersecting-mongoid-in-queries
I was able to reproduce it. This happens when using field "names" that are actually aliases (
id
→_id
and custom ones.)Trying to identify the code that produced it, I traced it down to Mergeable:
Now, it tries to perform
Selector#[]
with alias, not actual field name, so it gets nil, instead of selector for the real field. So it just uses the new selector.Selector#store
does respect aliases, however, so it overrides the existing selector with the new one. (Selector
is a subclass ofSmash
.)There are actually two ways to fix this, in my opinion:
Mergeable#with_strategy
try to resolve real field name itself and fetch appropriate selector for field.Selector#[]
(Smash#[]
) actually respect aliases that it was instantiated with.I don't think
Mergeable#with_strategy
should care about actual field names at this point so I opted for the second way.