Active Record And Will Paginate for Non-Rails Application
- Categories:
- ruby
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
- Tags:
- #tutorial
- #sinatra
- #ruby
- #active-record