« markaby_scaffold Rails Plugin | Main | Alan Cooper presented by IxDA at Hot Studio »
February 27, 2008
Using paginating_find with has_finder
I've been enjoying using has_finder by Nick at Pivotal Labs and recently added pagination to the application I am providing volunteer time to for the San Francisco Bike Kitchen.
I like the semantics of paginating_find over will_paginate but am not married to that choice if anyone wants to try to convince me otherwise.
In any case, I wanted to paginate the finders created by has_finder. I wrote a simple ActiveRecord mixin that provides a class method 'acts_as_paginated and is used in your model like:
class Visit < ActiveRecord::Base belongs_to :person acts_as_paginated :size=> 10 has_finder :for_person, lambda { |person| { :conditions => { :person_id => person}, :order => 'datetime DESC' } } has_finder :in_date_range, lambda { |from,to| { :conditions => [ "visits.datetime >= ? and visits.datetime <= ?", from, to ] } } end
Client code looks like:
from, to = Date.new(2008,2,1), Date.new(2008,2,3) visits = Visit.for_person(@person).in_date_range(from, to).paginate(:page => 3)
The mixin looks like:
# Provides Model.paginate(options={}) to allow
# the paginating_find plugin to be used with the has_finder plugin.
#
# Usage:
# acts_as_paginated
# acts_as_paginated :page => 2, size => 10
#
# Install:
# Save this file as lib/acts_as_paginated.rb and require 'acts_as_paginated'
# in environment.rb.
#
module HasFinder
module PaginatingFind #:nodoc:
def self.included(mod)
mod.extend(ClassMethods)
end
module ClassMethods
def acts_as_paginated(options={ :page => 1, :size => 20})
cattr_accessor :paginate_defaults
self.paginate_defaults = options
self.class_eval do
extend HasFinder::PaginatingFind::SingletonMethods
end
end
end
module SingletonMethods
def paginate(args={})
options = self.paginate_defaults.clone
options[:page] = args[:page].to_i if args[:page]
options[:size] = args[:size].to_i if args[:size]
find(:all, :page => { :size => options[:size], :current => options[:page], :first => 1 })
end
end
end
end
ActiveRecord::Base.send(:include, HasFinder::PaginatingFind)
It also works to paginate associations:
@person.visits.paginate(:size => 4)
Posted by Alon Salant at February 27, 2008 7:23 PM
