Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Explicit caching of criteria via #cache

  • Loading branch information...
commit d671f665921521216cae837840e235482a47d1af 1 parent 256737e
@durran durran authored
Showing with 52 additions and 20 deletions.
  1. +28 −20 lib/mongoid/criteria.rb
  2. +24 −0 spec/unit/mongoid/criteria_spec.rb
View
48 lib/mongoid/criteria.rb
@@ -94,6 +94,20 @@ def context
@context ||= determine_context
end
+ # Iterate over each +Document+ in the results. This can take an optional
+ # block to pass to each argument in the results.
+ #
+ # Example:
+ #
+ # <tt>criteria.each { |doc| p doc }</tt>
+ def each(&block)
+ return each_cached(&block) if cached?
+ if block_given?
+ execute.each { |doc| yield doc }
+ end
+ self
+ end
+
# Merges the supplied argument hash into a single criteria
#
# Options:
@@ -111,19 +125,6 @@ def fuse(criteria_conditions = {})
end
end
- # Iterate over each +Document+ in the results. This can take an optional
- # block to pass to each argument in the results.
- #
- # Example:
- #
- # <tt>criteria.each { |doc| p doc }</tt>
- def each(&block)
- if block_given?
- execute.each { |doc| yield doc }
- end
- self
- end
-
# Create the new +Criteria+ object. This will initialize the selector
# and options hashes, as well as the type of criteria.
#
@@ -198,10 +199,7 @@ def scoped
# Example:
#
# <tt>Criteria.translate(Person, "4ab2bc4b8ad548971900005c")</tt>
- #
# <tt>Criteria.translate(Person, :conditions => { :field => "value"}, :limit => 20)</tt>
- #
- # Returns a new +Criteria+ object.
def self.translate(*args)
klass = args[0]
params = args[1] || {}
@@ -220,10 +218,6 @@ def self.translate(*args)
# Example:
#
# <tt>criteria#determine_context</tt>
- #
- # Returns:
- #
- # A enumerable or mongo context.
def determine_context
if @klass.embedded
return Contexts::Enumerable.new(@selector, @options, @documents)
@@ -231,6 +225,20 @@ def determine_context
Contexts::Mongo.new(@selector, @options, @klass)
end
+ # Iterate over each +Document+ in the results and cache the collection.
+ def each_cached(&block)
+ @collection ||= execute
+ if block_given?
+ docs = []
+ @collection.each do |doc|
+ docs << doc
+ yield doc
+ end
+ @collection = docs
+ end
+ self
+ end
+
# Filters the unused options out of the options +Hash+. Currently this
# takes into account the "page" and "per_page" options that would be passed
# in if using will_paginate.
View
24 spec/unit/mongoid/criteria_spec.rb
@@ -316,6 +316,30 @@
end
+ context "when caching" do
+
+ before do
+ Person.expects(:collection).returns(@collection)
+ @collection.expects(:find).with({ :_type => { "$in" => ["Doctor", "Person"] }, :title => "Sir" }, {}).returns(@cursor)
+ @cursor.expects(:each).yields(@person)
+ @criteria.cache
+ @criteria.each do |doc|
+ doc.should == @person
+ end
+ end
+
+ it "caches the results of the cursor iteration" do
+ @criteria.each do |doc|
+ doc.should == @person
+ end
+ # Do it again for sanity's sake.
+ @criteria.each do |doc|
+ doc.should == @person
+ end
+ end
+
+ end
+
end
describe "#first" do
Please sign in to comment.
Something went wrong with that request. Please try again.