lib/mongoid/contexts/enumerable.rb in mongoid-pre-2.0.0.beta1 vs lib/mongoid/contexts/enumerable.rb in mongoid-pre-2.0.0.pre

- old
+ new

@@ -1,14 +1,13 @@ # encoding: utf-8 module Mongoid #:nodoc: module Contexts #:nodoc: class Enumerable - include Ids, Paging - attr_reader :criteria + include Paging + attr_reader :selector, :options, :documents - delegate :blank?, :empty?, :first, :last, :to => :execute - delegate :documents, :options, :selector, :to => :criteria + delegate :first, :last, :to => :execute # Return aggregation counts of the grouped documents. This will count by # the first field provided in the fields array. # # Returns: @@ -18,80 +17,46 @@ counts = {} group.each_pair { |key, value| counts[key] = value.size } counts end - # Get the average value for the supplied field. - # - # Example: - # - # <tt>context.avg(:age)</tt> - # - # Returns: - # - # A numeric value that is the average. - def avg(field) - total = sum(field) - total ? (total.to_f / count) : nil - end - # Gets the number of documents in the array. Delegates to size. def count - @count ||= documents.size + @count ||= @documents.size end - # Gets an array of distinct values for the supplied field across the - # entire array or the susbset given the criteria. + # Groups the documents by the first field supplied in the field options. # - # Example: + # Returns: # - # <tt>context.distinct(:title)</tt> - def distinct(field) - execute.collect { |doc| doc.send(field) }.uniq + # A +Hash+ with field values as keys, arrays of documents as values. + def group + field = @options[:fields].first + @documents.group_by { |doc| doc.send(field) } end # Enumerable implementation of execute. Returns matching documents for # the selector, and adds options if supplied. # # Returns: # # An +Array+ of documents that matched the selector. def execute(paginating = false) - limit(documents.select { |document| document.matches?(selector) }) + limit(@documents.select { |document| document.matches?(@selector) }) end - # Groups the documents by the first field supplied in the field options. - # - # Returns: - # - # A +Hash+ with field values as keys, arrays of documents as values. - def group - field = options[:fields].first - documents.group_by { |doc| doc.send(field) } - end - # Create the new enumerable context. This will need the selector and # options from a +Criteria+ and a documents array that is the underlying # array of embedded documents from a has many association. # # Example: # - # <tt>Mongoid::Contexts::Enumerable.new(criteria)</tt> - def initialize(criteria) - @criteria = criteria + # <tt>Mongoid::Contexts::Enumerable.new(selector, options, docs)</tt> + def initialize(selector, options, documents) + @selector, @options, @documents = selector, options, documents end - # Iterate over each +Document+ in the results. This can take an optional - # block to pass to each argument in the results. - # - # Example: - # - # <tt>context.iterate { |doc| p doc }</tt> - def iterate(&block) - execute.each(&block) - end - # Get the largest value for the field in all the documents. # # Returns: # # The numerical largest value. @@ -119,31 +84,29 @@ # # Returns: # # The numerical sum of all the document field values. def sum(field) - sum = documents.inject(nil) do |memo, doc| + sum = @documents.inject(nil) do |memo, doc| value = doc.send(field) memo ? memo += value : value end end protected # If the field exists, perform the comparison and set if true. def determine(field, operator) - matching = documents.inject(nil) do |memo, doc| + matching = @documents.inject(nil) do |memo, doc| value = doc.send(field) (memo && memo.send(operator, value)) ? memo : value end end # Limits the result set if skip and limit options. def limit(documents) - skip, limit = options[:skip], options[:limit] + skip, limit = @options[:skip], @options[:limit] if skip && limit return documents.slice(skip, limit) - elsif limit - return documents.first(limit) end documents end end end