mongoid / origin

A Ruby DSL for building MongoDB queries
http://mongoid.org/en/origin/index.html
MIT License
62 stars 29 forks source link

Origin::Smash should respect aliases when fetching #83

Closed goshacmd closed 11 years ago

goshacmd commented 11 years ago

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:

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:

  1. Make Mergeable#with_strategy try to resolve real field name itself and fetch appropriate selector for field.
  2. 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.

durran commented 11 years ago

Can you add a spec on the smash_spec as well for this please?

goshacmd commented 11 years ago

Sure, just added the specs.