Can rails scopes filter on the number of associate

2019-05-19 05:02发布

问题:

I am using Rails 3 with Mongoid.

I have a Folder class that can then be shared with other User classes as such

class Folder
  has_one :owner
  has_many :users

I am trying to create two scopes one that can be used to return all private folders, and one to return all shared folders. Is there any way to count the number of associations within a scope?

  scope :personal, where(:users.count => 0)    #Erroring on count...
  scope :shared, where(:users.count.gt => 0)  #Erroring on count...

I've considered building methods instead but would prefer scopes as I wish to chain them with other scopes.

回答1:

Since you're accessing referenced documents - your users method is a virtual attribute, which you can't access during your query. You can however use user_ids (the array of User ids in your Folder document) to perform the kinds of queries you want:

Either of these should work for your personal scope:

scope :personal, where(:user_ids.size => 0)
# or
scope :personal, where(:user_ids => [])

And for your shared scope:

scope :shared, where(:user_ids.ne => [])


回答2:

scope :personal, where({ "$or" => [{:user_ids => nil}, {:user_ids => {"$size"=>0}}] })
scope :shared, where({ "$nor" => [{:user_ids => nil}, {:user_ids => {"$size"=>0}}] })

This should handle both the cases when :user_ids is not set or is null and when it is set to an empty array.