2

I have the next models, using Mongoid:

class Album
  have_many :images
end

class Image
  belongs_to :album
end

I want to get only albums that have any images:

Album.all.select{ |a| a.images.count > 0 }

But it return an array and I need a Mongoid::Criteria. I tried using something like:

Album.where( "this.images.count > 0" )

and it always return 0 elements. ¿ How can I do it ?

rjurado01
  • 5,337
  • 3
  • 36
  • 45
  • I am not sure but this `Album.joins(:images)` should return an array of albums who has at least one image - to check on your side: I'm not that sure about it. – MrYoshiji Nov 15 '12 at 16:53

1 Answers1

1

Actually that is not an array, and it is a Proxy. you can check the logs and see that moped is calling .count funcion for every album(2 in my case).

1.9.3-p194 :043 > Album.each { |a| a.images.count }
  MOPED: 127.0.0.1:27017 QUERY        database=mongo_benchmark collection=albums selector={} flags=[] limit=0 skip=0 fields=nil (0.7441ms)
  MOPED: 127.0.0.1:27017 COMMAND      database=mongo_benchmark command={:count=>"images", :query=>{"album_id"=>"50e36dd17c71c110ff000001"}} (0.5209ms)
  MOPED: 127.0.0.1:27017 COMMAND      database=mongo_benchmark command={:count=>"images", :query=>{"album_id"=>"50e36f8f7c71c110ff000004"}} (0.3800ms)

Also if you want to get the Criteria object you can do album.images.scoped

If you have lots of albums it will call count for ever one, which is not good. I would advise you to use a counter cache in this situation. you can use a branch that I have including counter cache to mongoid https://github.com/arthurnn/mongoid/tree/2215-counter_cache

Arthur Neves
  • 11,840
  • 8
  • 60
  • 73