Update 2020-01-19: this tutorial is based on old version Will Paginate and Sinatra, I will update this next time.
I’m new to Sinatra and I want to use it together with Active Record and Will Paginate. After hours searching, I’ve finally found out to use active_record and will_paginate for non Rails application. Before I explain use Active Record and Will Paginate for non-Rails app, I assume that you use bundler and your database migration is already setup and working.
Step 1. Gemfile First thing first, edit your Gemfile.
# Gemfile
source :rubygems
gem 'sinatra' , '1.0.0' , :require => 'sinatra/base'
gem 'activerecord' , '3.0.0.rc' , :require => 'active_record'
gem 'haml'
gem 'will_paginate' , :git => 'git://github.com/mislav/will_paginate.git' ,
:tag => 'v3.0.pre2' ,
:require => 'will_paginate/finders/base'
Step 2. Edit Your Model You must extend your class model with Will Paginate module.
# your_model.rb
class Article < ActiveRecord :: Base
extend WillPaginate :: Finders :: Base
end
Step 3. Edit your Sinatra Application Because Will Paginate helper does not work with Sinatra Application, so you need to write your own helper.
# your_sinatra_app.rb
require 'rubygems'
require 'bundler/setup'
Bundler . require :default
require 'your_model.rb'
class Application < Sinatra :: Base
get '/' do
@articles = Article . order ( "created_at desc" ).
paginate :page => params [ :page ], :per_page => 10
haml :articles
end
helpers do
# helper for pagination
def paginate ( resources )
if ! resources . next_page . nil? and ! resources . previous_page . nil?
html = "« Prev "
html += " #{ params [ :page ] } of #{ resources . total_pages } "
html += "Next »"
elsif ! resources . next_page . nil? and resources . previous_page . nil?
html = "Next »"
elsif resources . next_page . nil? and ! resources . previous_page . nil?
html = "« Prev "
html += " #{ params [ :page ] } of #{ resources . total_pages } "
end
return html
end
end
end
Step 4. Edit Your View # views/articles.haml
% div
% header
% h2
Article list
. content
% table
% thead
% tr
% th
Title
% th
Content
% th
Author
% tbody
- @articles . each do | article |
% tr
% td
= article . title
% td
= article . content
% td
= article . author
= paginate @articles
Done. Sinatra, Will Paginate, and Active Record are ready to use. The above code is extracted from my Sinatrails project, feel free to use it.
Update in 2012: New code for step 3.
# your_sinatra_app.rb
require 'rubygems'
require 'bundler/setup'
Bundler . require :default
require 'your_model.rb'
class Application < Sinatra :: Base
get '/' do
@articles = Article . order ( "created_at desc" ).
paginate :page => params [ :page ], :per_page => 10
haml :articles
end
# inspired from http://pastie.org/1192729 by krishnaprasad
helpers do
def to_params ( params_hash )
new_params = ''
stack = []
params_hash . each do | k , v |
unless k == "page"
if v . is_a? ( Hash )
stack << [ k , v ]
else
new_params << " #{ k } = #{ v } &"
end
end
end
stack . each do | parent , hash |
hash . each do | k , v |
unless k == "page"
if v . is_a? ( Hash )
stack << [ " #{ parent } [ #{ k } ]" , v ]
else
new_params << " #{ parent } [ #{ k } ]= #{ v } &"
end
end
end
end
new_params . chop! # trailing &
"&" + new_params unless new_params . empty?
end
def paginate ( resources )
parameters = to_params ( params . clone )
if ! resources . next_page . nil? and ! resources . previous_page . nil?
html = %^<a href=" #{ request . path_info } ?page= #{ resources . previous_page }#{ parameters } ">« Prev</a> ^
html += " #{ params [ :page ] } of #{ resources . total_pages } "
html += %^<a href=" #{ request . path_info } ?page= #{ resources . next_page }#{ parameters } ">Next »</a>^
elsif ! resources . next_page . nil? and resources . previous_page . nil?
html = %^<a href=" #{ request . path_info } ?page= #{ resources . next_page }#{ parameters } ">Next »</a>^
elsif resources . next_page . nil? and ! resources . previous_page . nil?
html = %^<a href=" #{ request . path_info } ?page= #{ resources . previous_page }#{ parameters } ">« Prev</a> ^
html += " #{ params [ :page ] } of #{ resources . total_pages } "
end
html
end
end
end