Desi McAdam

July 24, 2007

will_paginate array?

Filed under: Uncategorized — desi.mcadam @ 5:11 am

Today I started putting pagination in the app that I have been working on. Based on recommendations from Obie I decided to use “will_paginate”, a rails plugin for pagination put out by the err the blog guys. It worked amazingly and the view helper was great! I really like the fact that I can apply the same look and feel to all page pagination throughout the app… well umm.. until I wanted to add pagination to a collection not generated from a finder or association. Since I really wanted everything to look the same and behave the same I did the following little trick so that you can call paginate on a plain old array.

class Array
  def paginate(page=1, per_page=15)
    pagination_array = WillPaginate::Collection.new(page, per_page, self.size)
    start_index = pagination_array.offset
    end_index = start_index + (per_page - 1)
    array_to_concat = self[start_index..end_index]
    array_to_concat.nil? ? [] : pagination_array.concat(array_to_concat)
  end
end

Before folks say anything about the above code.. yes I know it could be more concise if I didn’t use all the local variables but I wanted it to be really clear what I was doing here so.. leave it alone.

Now basically you can say

myarray.paginate(params[:page], per_page)

If you want to see it work yourself feel free to run this spec.


require File.dirname(__FILE__) + ‘/../spec_helper’

describe ‘Given we call paginate on an array’ do
  it ’should return an array containing the first 3 elements of the org array when page = 1 and per_page_count = 3′ do
    array = [”a”,”b”,”c”,”d”,”e”]
    current_page = 1
    show_per_page = 3
    expected_array = [”a”, “b”, “c”]
    (array.paginate(current_page, show_per_page)).should == expected_array
  end

  it ’should return an array containing the last 2 elements of the org array when page = 2 and per_page_count = 3′ do
    array = [”a”,”b”,”c”,”d”,”e”]
    current_page = 2
    show_per_page = 3
    expected_array = [”d”, “e”]
    (array.paginate(current_page, show_per_page)).should == expected_array
  end

  it ’should return an array containing all the elements of the org array when page = 1 and per_page_count = 5′ do
    array = [”a”,”b”,”c”,”d”,”e”]
    current_page = 1
    show_per_page = 5
    expected_array = [”a”,”b”,”c”,”d”,”e”]
    (array.paginate(current_page, show_per_page)).should == expected_array
  end

  it ’should return an array containing all the elements of the org array when page = 1 and per_page_count greater than org number of elements i.e = 6′ do
    array = [”a”,”b”,”c”,”d”,”e”]
    current_page = 1
    show_per_page = 6
    expected_array = [”a”,”b”,”c”,”d”,”e”]
    (array.paginate(current_page, show_per_page)).should == expected_array
  end

  it ’should return an empty array if you ask for a page that does not exist’ do
    array = [”a”,”b”,”c”,”d”,”e”]
    current_page = 3
    show_per_page = 5
    expected_array = []
    (array.paginate(current_page, show_per_page)).should == expected_array
  end

  it ’should return an empty array if you ask for a negative page number’ do
    array = [”a”,”b”,”c”,”d”,”e”]
    current_page = -1
    show_per_page = 5
    expected_array = []
    (array.paginate(current_page, show_per_page)).should == expected_array
  end

  it ’should return an empty array if you ask for a negative per_page number’ do
    array = [”a”,”b”,”c”,”d”,”e”]
    current_page = 1
    show_per_page = -5
    expected_array = []
    (array.paginate(current_page, show_per_page)).should == expected_array
  end
end

Powered by WordPress