From 3a1e88a308c625371a8738ebf3a4c848cb2069ed Mon Sep 17 00:00:00 2001 From: Durran Jordan Date: Mon, 6 Feb 2012 12:51:32 +0100 Subject: [PATCH] Allow eager loading to work as a default scope. Fixes #1676. --- CHANGELOG.md | 2 + lib/mongoid/criteria.rb | 1 + lib/mongoid/criterion/inclusion.rb | 2 +- spec/mongoid/criterion/inclusion_spec.rb | 123 +++++++++++++++++++++++ 4 files changed, 127 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 39b96d1731..e288665de8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -71,6 +71,8 @@ For instructions on upgrading to newer versions, visit ### Resolved Issues +* \#1676 Allow eager loading to work as a default scope. + * \#1665/#1672 Expand complex criteria in nested criteria selectors, like #matches. (Hans Hasselberg) diff --git a/lib/mongoid/criteria.rb b/lib/mongoid/criteria.rb index bb407fe8de..df5bf5bed6 100644 --- a/lib/mongoid/criteria.rb +++ b/lib/mongoid/criteria.rb @@ -262,6 +262,7 @@ def as_conditions scope_options = @options.dup sorting = scope_options.delete(:sort) scope_options[:order_by] = sorting if sorting + scope_options[:includes] = inclusions.map(&:name) if inclusions.any? { :where => @selector }.merge(scope_options) end alias :to_ary :to_a diff --git a/lib/mongoid/criterion/inclusion.rb b/lib/mongoid/criterion/inclusion.rb index 82367e6d6a..09c9399b18 100644 --- a/lib/mongoid/criterion/inclusion.rb +++ b/lib/mongoid/criterion/inclusion.rb @@ -190,7 +190,7 @@ def in(attributes = {}) # # @since 2.2.0 def includes(*relations) - relations.each do |name| + relations.flatten.each do |name| inclusions.push(klass.reflect_on_association(name)) end clone diff --git a/spec/mongoid/criterion/inclusion_spec.rb b/spec/mongoid/criterion/inclusion_spec.rb index 04a28fb3e7..16420c332a 100644 --- a/spec/mongoid/criterion/inclusion_spec.rb +++ b/spec/mongoid/criterion/inclusion_spec.rb @@ -636,6 +636,129 @@ Person.create end + context "when providing inclusions to the default scope" do + + before do + Person.default_scope(Person.includes(:posts)) + end + + after do + Person.default_scoping = nil + end + + let!(:post_one) do + person.posts.create(:title => "one") + end + + let!(:post_two) do + person.posts.create(:title => "two") + end + + context "when the criteria has no options" do + + before do + Mongoid::IdentityMap.clear + end + + let!(:criteria) do + Person.all.entries + end + + it "returns the correct documents" do + criteria.should eq([ person ]) + end + + it "inserts the first document into the identity map" do + Mongoid::IdentityMap[Post.collection_name][post_one.id].should eq(post_one) + end + + it "inserts the second document into the identity map" do + Mongoid::IdentityMap[Post.collection_name][post_two.id].should eq(post_two) + end + end + + context "when calling first on the criteria" do + + before do + Mongoid::IdentityMap.clear + end + + let!(:from_db) do + Person.first + end + + it "returns the correct documents" do + from_db.should eq(person) + end + + it "inserts the first document into the identity map" do + Mongoid::IdentityMap[Post.collection_name][post_one.id].should eq(post_one) + end + + it "inserts the second document into the identity map" do + Mongoid::IdentityMap[Post.collection_name][post_two.id].should eq(post_two) + end + end + + context "when calling last on the criteria" do + + before do + Mongoid::IdentityMap.clear + end + + let!(:from_db) do + Person.last + end + + it "returns the correct documents" do + from_db.should eq(person) + end + + it "inserts the first document into the identity map" do + Mongoid::IdentityMap[Post.collection_name][post_one.id].should eq(post_one) + end + + it "inserts the second document into the identity map" do + Mongoid::IdentityMap[Post.collection_name][post_two.id].should eq(post_two) + end + end + + context "when the criteria has limiting options" do + + let!(:person_two) do + Person.create + end + + let!(:post_three) do + person_two.posts.create(:title => "three") + end + + before do + Mongoid::IdentityMap.clear + end + + let!(:criteria) do + Person.asc(:_id).limit(1).entries + end + + it "returns the correct documents" do + criteria.should eq([ person ]) + end + + it "inserts the first document into the identity map" do + Mongoid::IdentityMap[Post.collection_name][post_one.id].should eq(post_one) + end + + it "inserts the second document into the identity map" do + Mongoid::IdentityMap[Post.collection_name][post_two.id].should eq(post_two) + end + + it "does not insert the third post into the identity map" do + Mongoid::IdentityMap[Post.collection_name][post_three.id].should be_nil + end + end + end + context "when including a has and belongs to many" do let!(:preference_one) do