Skip to content
Browse files

refs #47, #68, #74 generic pagination support for Array object

this enables you to paginate through any Arrayish object in this way:
  Kaminari.paginate_array(my_array_object).page(params[:page]).per(10)
  • Loading branch information...
1 parent ca38024 commit e04f65aeaa420600577c5f15e732f1cfcd2526fe @amatsuda committed Apr 22, 2011
Showing with 148 additions and 0 deletions.
  1. +42 −0 lib/kaminari/models/array_extension.rb
  2. +1 −0 lib/kaminari/railtie.rb
  3. +105 −0 spec/models/array_spec.rb
View
42 lib/kaminari/models/array_extension.rb
@@ -0,0 +1,42 @@
+module Kaminari
+ # Kind of Array that can paginate
+ class PaginatableArray < Array
+ include Kaminari::ConfigurationMethods::ClassMethods
+
+ attr_internal_accessor :limit_value, :offset_value
+
+ def initialize(original_array, limit_val = default_per_page, offset_val = 0) #:nodoc:
+ @_original_array, @_limit_value, @_offset_value = original_array, limit_val, offset_val
+ super (original_array[offset_val, limit_val] || [])
+ end
+
+ # items at the specified "page"
+ def page(num = 1)
+ offset(limit_value * ([num.to_i, 1].max - 1))
+ end
+
+ # returns another chunk of the original array
+ def limit(num)
+ self.class.new @_original_array, num, offset_value
+ end
+
+ # total item numbers of the original array
+ def total_count
+ @_original_array.count
+ end
+
+ # returns another chunk of the original array
+ def offset(num)
+ arr = self.class.new @_original_array, limit_value, num
+ class << arr
+ include Kaminari::PageScopeMethods
+ end
+ arr
+ end
+ end
+
+ # Wrap an Array object to make it paginatable
+ def self.paginate_array(array)
+ PaginatableArray.new array
+ end
+end
View
1 lib/kaminari/railtie.rb
@@ -20,6 +20,7 @@ class Railtie < ::Rails::Railtie #:nodoc:
::Mongoid::Document.send :include, Kaminari::MongoidExtension::Document
::Mongoid::Criteria.send :include, Kaminari::MongoidExtension::Criteria
end
+ require File.join(File.dirname(__FILE__), 'models/array_extension')
ActiveSupport.on_load(:action_view) do
::ActionView::Base.send :include, Kaminari::ActionViewExtension
end
View
105 spec/models/array_spec.rb
@@ -0,0 +1,105 @@
+require File.expand_path('../spec_helper', File.dirname(__FILE__))
+
+describe Kaminari::PaginatableArray do
+ let(:array) { Kaminari::PaginatableArray.new((1..100).to_a) }
+ describe '#page' do
+ shared_examples_for 'the first page of array' do
+ it { should have(25).users }
+ its(:first) { should == 1 }
+ end
+
+ shared_examples_for 'blank array page' do
+ it { should have(0).items }
+ end
+
+ context 'page 1' do
+ subject { array.page 1 }
+ it_should_behave_like 'the first page of array'
+ end
+
+ context 'page 2' do
+ subject { array.page 2 }
+ it { should have(25).users }
+ its(:first) { should == 26 }
+ end
+
+ context 'page without an argument' do
+ subject { array.page }
+ it_should_behave_like 'the first page of array'
+ end
+
+ context 'page < 1' do
+ subject { array.page 0 }
+ it_should_behave_like 'the first page of array'
+ end
+
+ context 'page > max page' do
+ subject { array.page 5 }
+ it_should_behave_like 'blank array page'
+ end
+ end
+
+ describe '#per' do
+ context 'page 1 per 5' do
+ subject { array.page(1).per(5) }
+ it { should have(5).users }
+ its(:first) { should == 1 }
+ end
+ end
+
+ describe '#num_pages' do
+ context 'per 25 (default)' do
+ subject { array.page }
+ its(:num_pages) { should == 4 }
+ end
+
+ context 'per 7' do
+ subject { array.page(2).per(7) }
+ its(:num_pages) { should == 15 }
+ end
+
+ context 'per 65536' do
+ subject { array.page(50).per(65536) }
+ its(:num_pages) { should == 1 }
+ end
+
+ context 'per 0 (using default)' do
+ subject { array.page(50).per(0) }
+ its(:num_pages) { should == 4 }
+ end
+
+ context 'per -1 (using default)' do
+ subject { array.page(5).per(-1) }
+ its(:num_pages) { should == 4 }
+ end
+
+ context 'per "String value that can not be converted into Number" (using default)' do
+ subject { array.page(5).per('aho') }
+ its(:num_pages) { should == 4 }
+ end
+ end
+
+ describe '#current_page' do
+ context 'page 1' do
+ subject { array.page }
+ its(:current_page) { should == 1 }
+ end
+
+ context 'page 2' do
+ subject { array.page(2).per 3 }
+ its(:current_page) { should == 2 }
+ end
+ end
+
+ describe '#count' do
+ context 'page 1' do
+ subject { array.page }
+ its(:count) { should == 25 }
+ end
+
+ context 'page 2' do
+ subject { array.page 2 }
+ its(:count) { should == 25 }
+ end
+ end
+end

0 comments on commit e04f65a

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