From 4276a2c4b3ed18691e2615745c169dc9d1fff89a Mon Sep 17 00:00:00 2001 From: Yuki Nishijima Date: Thu, 25 Aug 2011 06:30:45 +0900 Subject: [PATCH] enable to paginate throurh embedded documents in mongoid --- .../models/mongoid_criteria_methods.rb | 10 ++- lib/kaminari/models/mongoid_extension.rb | 2 +- spec/models/mongoid_spec.rb | 65 +++++++++++++++++-- 3 files changed, 71 insertions(+), 6 deletions(-) diff --git a/lib/kaminari/models/mongoid_criteria_methods.rb b/lib/kaminari/models/mongoid_criteria_methods.rb index 221336369..1d94fbca3 100644 --- a/lib/kaminari/models/mongoid_criteria_methods.rb +++ b/lib/kaminari/models/mongoid_criteria_methods.rb @@ -11,7 +11,15 @@ def offset_value #:nodoc: end def total_count #:nodoc: - count + embedded? ? unpage.count : count + end + + private + def unpage + clone.tap do |crit| + crit.options.delete :limit + crit.options.delete :skip + end end end end diff --git a/lib/kaminari/models/mongoid_extension.rb b/lib/kaminari/models/mongoid_extension.rb index 8377ec74b..b79109175 100644 --- a/lib/kaminari/models/mongoid_extension.rb +++ b/lib/kaminari/models/mongoid_extension.rb @@ -7,7 +7,7 @@ module Criteria included do def page(*args) - self.klass.page(*args).criteria.merge(self) + super(*args).criteria.merge(self) end end end diff --git a/spec/models/mongoid_spec.rb b/spec/models/mongoid_spec.rb index f8ab51c5c..41116d6f4 100644 --- a/spec/models/mongoid_spec.rb +++ b/spec/models/mongoid_spec.rb @@ -9,11 +9,12 @@ class Developer field :salary, :type => Integer end end - before do - stub(subject).count { 300 } # in order to avoid DB access... - end describe '#page' do + before do + stub(subject).count { 300 } # in order to avoid DB access... + end + context 'page 1' do subject { Developer.page 1 } it { should be_a Mongoid::Criteria } @@ -58,10 +59,13 @@ class Developer its(:num_pages) { should == 12 } it { should skip 25 } end - end describe '#per' do + before do + stub(subject).count { 300 } # in order to avoid DB access... + end + subject { Developer.page(2).per(10) } it { should be_a Mongoid::Criteria } its(:current_page) { should == 2 } @@ -69,4 +73,57 @@ class Developer its(:num_pages) { should == 30 } it { should skip 10 } end + + describe '#page in embedded documents' do + before :all do + class MongoDeveloper + include ::Mongoid::Document + field :salary, :type => Integer + embeds_many :frameworks + end + + class Framework + include ::Mongoid::Document + field :name, :type => String + field :language, :type => String + embedded_in :mongo_developer + end + end + + before :all do + @mongo_developer = MongoDeveloper.new + @mongo_developer.frameworks.new(:name => "rails", :language => "ruby") + @mongo_developer.frameworks.new(:name => "merb", :language => "ruby") + @mongo_developer.frameworks.new(:name => "sinatra", :language => "ruby") + @mongo_developer.frameworks.new(:name => "cakephp", :language => "php") + @mongo_developer.frameworks.new(:name => "tornado", :language => "python") + end + + context 'page 1' do + subject { @mongo_developer.frameworks.page(1).per(1) } + it { should be_a Mongoid::Criteria } + its(:total_count) { should == 5 } + its(:limit_value) { should == 1 } + its(:current_page) { should == 1 } + its(:num_pages) { should == 5 } + end + + context 'with criteria after' do + subject { @mongo_developer.frameworks.page(1).per(2).where(:language => "ruby") } + it { should be_a Mongoid::Criteria } + its(:total_count) { should == 3 } + its(:limit_value) { should == 2 } + its(:current_page) { should == 1 } + its(:num_pages) { should == 2 } + end + + context 'with criteria before' do + subject { @mongo_developer.frameworks.where(:language => "ruby").page(1).per(2) } + it { should be_a Mongoid::Criteria } + its(:total_count) { should == 3 } + its(:limit_value) { should == 2 } + its(:current_page) { should == 1 } + its(:num_pages) { should == 2 } + end + end end