Module: EagerCounting::CountBy::ClassMethods
- Defined in:
- lib/eager_counting/count_by.rb
Instance Method Summary collapse
-
#count_by(association_target, scope = nil) ⇒ Object
Performs a count grouped by the given association.
Instance Method Details
#count_by(association_target, scope = nil) ⇒ Object
Performs a count grouped by the given association. This means it will return a hash mapping the ids of the associated objects to the number of rows this class has for each of them.
Example:
class Comment < ActiveRecord::Base
include EagerCounting::CountBy
belongs_to :author
belongs_to :commentable, polymorphic: true
end
Comment.count_by(:author) # => hash with author id mapped to number of comments this user made
You can call this method on any relation object of the class you included it on
Comment.where(spam: false).count_by(:author) # => will only count non spam comments
With the second argument you can also limit the scope of the association by which to count
Comment.count_by(:author, User.where(admin: false)) # => only count comments by non admin users
By passing an hash as the association you can count by joined associations
Comment.count_by(author: { city: :country }) # => count comments by the country their from
You can also use it on polymoprhic associations. For that the second parameter is necessary to select the type of things to count by.
Comment.count_by(:commentable, Picture.all) # => how many comments does each picture have?
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/eager_counting/count_by.rb', line 44 def count_by(association_target, scope = nil) association = deepest_value(association_target).to_s scope ||= association.camelize.constantize.all join = without_deepest_value(association_target) target_model = self if association_target.is_a? Hash target_model = deepest_value(join).to_s.singularize.camelize.constantize end query = joins(join) .merge(target_model.where(association => scope)) .group(association_column_name(target_model, association)) .count Hash.new(0).merge query end |