Uploaded image for project: 'Mongoid'
  1. Mongoid
  2. MONGOID-3047

criteria.empty? is false when criteria.exists? is false (should never happen?)

    XMLWordPrintable

    Details

    • Type: Task
    • Status: Closed
    • Resolution: Done
    • Affects Version/s: None
    • Fix Version/s: 3.1.5
    • Component/s: None
    • Labels:

      Description

      I'm having problems with empty?/blank? using mongoid 3.1.4. I'm running a query on one of my models that looks like this:

      > query
      => #<Mongoid::Criteria                                                                                   
      selector: {"invalidated_at"=>{"$ne"=>nil}, "job_id"=>"5195d50cd51a32fd00000022"}                       
        options:  {}                                                                                           
        class:    JobMatch                                                                                     
        embedded: false>
      

      When I see what's returned by the query I get nothing (which is what I expect):

      > query.to_a
      => []
      

      However, if I use a boolean method to check what's in the query I get contradictory results:

      > query.count
      0
      > query.exists?
      false
      > query.empty?
      false
      > query.blank?
      false
      

      Huh? Surely it's not possible for exists? to be false and empty? to be false at the same time? (In fact Mongoid::Contextual::Queryable.empty? is defined as !exists?)

      I've stepped through what's being executed when I run empty?, and it seems like it's doing this:

      lib/mongoid/criteria.rb:504 - method_missing()
      lib/mongoid/finders.rb:55 - empty?()
      

      Mongoid::Finders.empty? is defined as count == 0 but when the code actually runs here count is returning 1. So it seems like it might not be applying the scope? Or alternatively, maybe Mongoid::Contextual::Queryable should be before Mongoid::Finders in the ancestor chain of Mongoid::Criteria so it's definition of empty? is called instead?

      The ancestor chain of my criteria is shown below (in which I can't even see Mongoid::Contextual::Queryable - maybe that's the problem?):

      > query.class.ancestors
      => [Mongoid::Criteria,
       Kaminari::MongoidExtension::Criteria,
       Mongoid::Criterion::Scoping,
       Mongoid::Criterion::Modifiable,
       Mongoid::Criterion::Marshalable,
       Mongoid::Criterion::Findable,
       Mongoid::Criterion::Inspection,
       Origin::Queryable,
       Origin::Optional,
       Origin::Selectable,
       Origin::Mergeable,
       Mongoid::Contextual,
       Enumerable,
       Object,
       RSpec::Mocks::Methods,
       PP::ObjectMixin,
       Metaclass::ObjectMethods,
       Mocha::ObjectMethods,
       V8::Conversion::Object,
       ActiveSupport::Dependencies::Loadable,
       Mongoid::Extensions::Object,
       Moped::BSON::Extensions::Object,
       Origin::Extensions::Object,
       JSON::Ext::Generator::GeneratorMethods::Object,
       Kernel,
       BasicObject,
       BetterReceive]
      

      Also, what's interesting that it does work as expected in Mongoid 3.0.6 (I've tried stepping through the same thing with Mongoid 3.0.6 but I couldn't find which definition of empty? was being used)

      Surely empty? should be true when count == 0? (Or when !exists?)

        Attachments

          Activity

            People

            Assignee:
            durran Durran Jordan
            Reporter:
            iainbeeston iainbeeston
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved: