Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Merge pull request #67 from lardawge/generic_pagination_support

Generic pagination support
  • Loading branch information...
commit 08dc66b45179d3332987b95467aad70d1f444b84 2 parents 9dc7cb7 + 733f7db
Mat Brown authored June 28, 2011
18  sunspot/lib/sunspot/search/abstract_search.rb
... ...
@@ -1,3 +1,5 @@
  1
+require 'sunspot/search/paginated_collection'
  2
+
1 3
 module Sunspot
2 4
   module Search #:nodoc:
3 5
     
@@ -54,7 +56,7 @@ def execute! #:nodoc: deprecated
54 56
       # WillPaginate::Collection or Array:: Instantiated result objects
55 57
       #
56 58
       def results
57  
-        @results ||= maybe_will_paginate(verified_hits.map { |hit| hit.instance })
  59
+        @results ||= paginate_collection(verified_hits.map { |hit| hit.instance })
58 60
       end
59 61
   
60 62
       # 
@@ -85,7 +87,7 @@ def hits(options = {})
85 87
                   Hit.new(doc, highlights_for(doc), self)
86 88
                 end
87 89
               end
88  
-              maybe_will_paginate(hits || [])
  90
+              paginate_collection(hits || [])
89 91
             end
90 92
         end
91 93
       end
@@ -270,17 +272,11 @@ def highlights_for(doc)
270 272
       end
271 273
   
272 274
       def verified_hits
273  
-        @verified_hits ||= maybe_will_paginate(hits.select { |hit| hit.instance })
  275
+        @verified_hits ||= paginate_collection(hits.select { |hit| hit.instance })
274 276
       end
275 277
   
276  
-      def maybe_will_paginate(collection)
277  
-        if defined?(WillPaginate::Collection)
278  
-          WillPaginate::Collection.create(@query.page, @query.per_page, total) do |pager|
279  
-            pager.replace(collection)
280  
-          end
281  
-        else
282  
-          collection
283  
-        end
  278
+      def paginate_collection(collection)
  279
+        PaginatedCollection.new(collection, @query.page, @query.per_page, total)
284 280
       end
285 281
   
286 282
       def add_facet(name, facet)
55  sunspot/lib/sunspot/search/paginated_collection.rb
... ...
@@ -0,0 +1,55 @@
  1
+module Sunspot
  2
+  module Search
  3
+
  4
+    class PaginatedCollection
  5
+      instance_methods.each { |m| undef_method m unless m =~ /^__|instance_eval|object_id/ }
  6
+
  7
+      attr_reader :total_count, :current_page, :per_page
  8
+      alias :total_entries :total_count
  9
+      alias :limit_value :per_page
  10
+
  11
+      def initialize(collection, page, per_page, total)
  12
+        @collection   = collection
  13
+        @current_page = page
  14
+        @per_page     = per_page
  15
+        @total_count  = total
  16
+      end
  17
+
  18
+      def total_pages
  19
+        (total_count.to_f / per_page).ceil
  20
+      end
  21
+      alias :num_pages :total_pages
  22
+
  23
+      def first_page?
  24
+        current_page == 1
  25
+      end
  26
+
  27
+      def last_page?
  28
+        current_page >= total_pages
  29
+      end
  30
+
  31
+      def previous_page
  32
+        current_page > 1 ? (current_page - 1) : nil
  33
+      end
  34
+
  35
+      def next_page
  36
+        current_page < total_pages ? (current_page + 1) : nil
  37
+      end  
  38
+
  39
+      def out_of_bounds?
  40
+        current_page > total_pages
  41
+      end
  42
+      
  43
+      def offset
  44
+        (current_page - 1) * per_page
  45
+      end
  46
+
  47
+      private
  48
+
  49
+      def method_missing(method, *args, &block)
  50
+        @collection.send(method, *args, &block)
  51
+      end
  52
+
  53
+    end
  54
+  end
  55
+end
44  sunspot/spec/api/search/hits_spec.rb
@@ -12,38 +12,18 @@
12 12
     end.should == [['Post', post_1.id.to_s], ['Post', post_2.id.to_s]]
13 13
   end
14 14
 
15  
-  if ENV['USE_WILL_PAGINATE']
16  
-
17  
-    it 'returns search total as attribute of hits' do
18  
-      stub_results(Post.new, 4)
19  
-      session.search(Post) do
20  
-        paginate(:page => 1)
21  
-      end.hits.total_entries.should == 4
22  
-    end
23  
-
24  
-    it 'returns search total as attribute of verified hits' do
25  
-      stub_results(Post.new, 4)
26  
-      session.search(Post) do
27  
-        paginate(:page => 1)
28  
-      end.hits(:verify => true).total_entries.should == 4
29  
-    end
30  
-
31  
-  else
32  
-
33  
-    it 'returns vanilla array of hits if WillPaginate is not available' do
34  
-      stub_results(Post.new)
35  
-      session.search(Post) do
36  
-        paginate(:page => 1)
37  
-      end.hits.should_not respond_to(:total_entries)
38  
-    end
39  
-
40  
-    it 'returns vanilla array of verified hits if WillPaginate is not available' do
41  
-      stub_results(Post.new)
42  
-      session.search(Post) do
43  
-        paginate(:page => 1)
44  
-      end.hits(:verified => true).should_not respond_to(:total_entries)
45  
-    end
46  
-
  15
+  it 'returns search total as attribute of hits' do
  16
+    stub_results(Post.new, 4)
  17
+    session.search(Post) do
  18
+      paginate(:page => 1)
  19
+    end.hits.total_entries.should == 4
  20
+  end
  21
+
  22
+  it 'returns search total as attribute of verified hits' do
  23
+    stub_results(Post.new, 4)
  24
+    session.search(Post) do
  25
+      paginate(:page => 1)
  26
+    end.hits(:verify => true).total_entries.should == 4
47 27
   end
48 28
 
49 29
   it 'should return instance from hit' do
26  sunspot/spec/api/search/paginated_collection_spec.rb
... ...
@@ -0,0 +1,26 @@
  1
+require File.expand_path('spec_helper', File.dirname(__FILE__))
  2
+
  3
+describe "PaginatedCollection" do
  4
+  subject { Sunspot::Search::PaginatedCollection.new [], 1, 10, 20 }
  5
+
  6
+  it { subject.should be_an(Array) }
  7
+
  8
+  context "behaves like a WillPaginate::Collection" do
  9
+    it { subject.total_entries.should eql(20) }
  10
+    it { subject.total_pages.should eql(2) }
  11
+    it { subject.current_page.should eql(1) }
  12
+    it { subject.per_page.should eql(10) }
  13
+    it { subject.previous_page.should be_nil }
  14
+    it { subject.next_page.should eql(2) }
  15
+    it { subject.out_of_bounds?.should_not be_true }
  16
+    it { subject.offset.should eql(0) }
  17
+  end
  18
+
  19
+  context "behaves like Kaminari" do
  20
+    it { subject.total_count.should eql(20) }
  21
+    it { subject.num_pages.should eql(2) }
  22
+    it { subject.limit_value.should eql(10) }
  23
+    it { subject.first_page?.should be_true }
  24
+    it { subject.last_page?.should_not be_true }
  25
+  end
  26
+end
23  sunspot/spec/api/search/results_spec.rb
@@ -30,24 +30,11 @@
30 30
     session.search(Post).results.should == []
31 31
   end
32 32
 
33  
-  if ENV['USE_WILL_PAGINATE']
34  
-
35  
-    it 'returns search total as attribute of results' do
36  
-      stub_results(Post.new, 4)
37  
-      session.search(Post) do
38  
-        paginate(:page => 1)
39  
-      end.results.total_entries.should == 4
40  
-    end
41  
-
42  
-  else
43  
-
44  
-    it 'returns vanilla array if WillPaginate is not available' do
45  
-      stub_results(Post.new)
46  
-      session.search(Post) do
47  
-        paginate(:page => 1)
48  
-      end.results.should_not respond_to(:total_entries)
49  
-    end
50  
-
  33
+  it 'returns search total as attribute of results' do
  34
+    stub_results(Post.new, 4)
  35
+    session.search(Post) do
  36
+      paginate(:page => 1)
  37
+    end.results.total_entries.should == 4
51 38
   end
52 39
 
53 40
   it 'returns total' do
8  sunspot/spec/spec_helper.rb
@@ -5,14 +5,6 @@
5 5
 require 'ostruct'
6 6
 require 'sunspot'
7 7
 
8  
-if ENV['USE_WILL_PAGINATE']
9  
-  require 'will_paginate'
10  
-  require 'will_paginate/collection'
11  
-elsif ENV['USE_KAMINARI']
12  
-  module Kaminari
13  
-  end
14  
-end
15  
-
16 8
 require File.join(File.dirname(__FILE__), 'mocks', 'mock_record.rb')
17 9
 Dir.glob(File.join(File.dirname(__FILE__), 'mocks', '**', '*.rb')).each do |file|
18 10
   require file unless File.basename(file) == 'mock_record.rb'
2  sunspot/sunspot.gemspec
@@ -31,8 +31,6 @@ Gem::Specification.new do |s|
31 31
   s.add_dependency 'pr_geohash', '~> 1.0'
32 32
 
33 33
   s.add_development_dependency 'rspec', '~> 1.1'
34  
-  s.add_development_dependency 'activesupport'
35  
-  s.add_development_dependency 'will_paginate'
36 34
   s.add_development_dependency 'hanna'
37 35
 
38 36
   s.rdoc_options << '--webcvs=http://github.com/outoftime/sunspot/tree/master/%s' <<

0 notes on commit 08dc66b

Please sign in to comment.
Something went wrong with that request. Please try again.