Reputation: 343
I need to select transactions with the same type as a given transaction. And I need to check that it doesn't return all transactions with the nil type.
With ActiveRecord I can easily write:
given_transaction = Transaction.first
needed_transactions = Transaction.where('type != nil and type = ?', given_transaction.type)
and all works
when I try to write the same thing with mongoid:
needed_transactions = Transaction.where(:type => given_transaction.type, :type.ne => nil)
It generates the following query:
"query"=>{:type=>{"$ne"=>"planned"}}
In other words, mongoid ignores the first check and only uses the last check on the field.
I tried "all_of", "all_in", "and" — and still can't find the working solution.
Maybe I am doing something wrong... My world is going upside down because of this... :(((
Upvotes: 2
Views: 1372
Reputation: 434665
From the fine manual:
All queries in Mongoid are Criteria, which is a chainable and lazily evaluated wrapper to a MongoDB dynamic query.
And looking at the Criteria docs for where
we see a bunch of examples with a single condition. But remember the chainability mentioned above. Perhaps you're looking for this:
needed_transactions = Transaction.where(:type => given_transaction.type).where(:type.ne => nil)
The Criteria#and
docs might make good reading as well:
Adds another simple expression that must match in order to return results. This is the same as
Criteria#where
and is mostly here for syntactic sugar.MONGOID # Match all people with last name Jordan and first name starting with d. Person.where(last_name: "Jordan").and(first_name: /^d/i) MONGODB QUERY SELECTOR { "last_name" : "Jordan", "first_name" : /^d/i }
I have to admit that I don't understand why you're checking :type
twice like that though; if given_transaction.type.nil?
is possible then you could deal with that without even querying your database.
And BTW, with ActiveRecord you'd want to say this:
Transaction.where('type is not null and type = ?', given_transaction.type)
As far as the strange query you're getting is concerned, when you do this:
Transaction.where(:type => given_transaction.type, :type.ne => nil)
Mongoid ends up trying to build a Hash with two values for the :type
key:
{ :type => 'planned' }
{ :type => { :$ne => nil } }
and somehow it ends up replacing the nil
with 'planned'
. I don't know the internal details of Mongoid's where
or the methods it patches into Symbol, I'm just backtracking from the observed behavior.
Upvotes: 6