sexta-feira, 10 de outubro de 2008

Paginação fácil em Rails com Will Paginate

Sim, é claro que você já precisou paginar resultados na sua aplicação web. No nosso post de hoje, vou falar do Will Paginate, um ótima biblioteca para fazer isso em Rails.

Como de costume, vamos criar um novo projeto (listagem de tarefas):

rails mytasks
cd mytasks
rake db:create:all


Muito bem, vamos então preparar nosso model e nosso controller com 2 metodos apenas. Um para listar as tasks e um para criar tasks virtuais pra nós - Não vou cobrir todas as etapas CRUD aqui pois este não é o foco e imagino que nem precisemos disto.

script/generate model task title:string description:text
rake db:migrate
script/generate controller tasks index generate


Com nosso controller criado, vamos implementar os dois metodos reponsáveis por nossas actions. A primeira vai simplesmente listar as tasks, enquanto a segunda vai criar registros de tasks no banco (e, claro, remover as existentes também)

app/controllers/tasks_controller.rb

class TasksController < ApplicationController

def index
@tasks = Task.find(:all)
end

def generate
Task.delete_all
50.times do |i|
task = Task.create(:title => "Task number #{i}", :description => "Description for task number #{i}")
end
flash[:notice] = "50 fresh new tasks created!"
redirect_to :action => 'index'
end

end

Ok, nosso controller esta preparado para o iní do nosso propósito. vamos entao deixar os templates preparados tambem.

app/views/tasks/index.html.erb

<h1>My Tasks</h1>
<% if flash[:notice] %>
<h3><%= flash[:notice] %></h3>
<% end %>
<% for task in @tasks %>
<p>
<b><%= task.title %></b><br/>
<i><%= task.description %></i>
</p>
<% end %>


Nao precisamos do view do generate, claro:

rm app/views/tasks/generate.html.erb

Vamos entao iniciar nosso server para ter certeza que tudo esta ok ate aqui:

script/server

Accesse diretamente o metodo para criar as tasks em seu controller:

http://localhost:3000/tasks/generate

Ok, ja temos nossas tasks, e nossa página principal para listá-las. O único problema, claro, é que precisamos de uma paginação.

Para começar, precisamos instalar a biblioteca, que na verdade está disponibilizado na forma de uma ruby gem. Vamos então usar o gem install. Adicione o GitHub no seu gem sources se você ainda nao tiver:

gem sources -a http://gems.github.com

Instale a biblioteca:

(sudo) gem install mislav-will_paginate

A instalação de uma gem é um pouco diferente da de um plugin. No nosso caso, precisamos agora adicionar a chamada &acrave; nossa biblioteca no nosso environment.rb:

config/environment.rb

Rails::Initializer.run do |config|
...
end

require "will_paginate"

Reinicie o seu servidor para que as alterações tenham efeito.

Agora precisamos alterar nosso controller, para adaptar o paginate &acrave; nossa lista de tasks:

app/controllers/tasks_controller.rb

def index

#@tasks = Task.find(:all) - podemos remover esta linha
@tasks = Task.paginate :page => params[:page], :per_page => 20

end

Visualize sua pagina no browser, para ver que agora so temos 20 resultados na pagina. Precisamos então conseguir acessar as outras páginas... o que é, como sempre, é uma tarefa muito fácil:

app/views/tasks/index.html.erb

<h1>My Tasks</h1>
<% if flash[:notice] %>
<h3><%= flash[:notice] %></h3>
<% end %>
<% for task in @tasks %>
<p>
<b><%= task.title %></b><br/>
<i><%= task.description %></i>
</p>
<% end %>

<%= will_paginate @tasks %>

Bom, eu avisei que era fácil!

Mas e Filtros, Orders e etc?

Sim, o Will Paginate também cobre problemas comuns como estes. Na verdade, a nossa biblioteca funciona tão bem como o find do ActiveRecord, permitindo brincadeiras como esta:

@products = Product.paginate_by_category_id @category.id, :page => params[:page], :order => 'price'


Chegamos ao fim de mais um post sobre bibliotecas e plugins rails. Espero que tenha sido util!

Até a próxima!

Um comentário:

Unknown disse...

Eu achei ótimo a postagem, porém, na minha página de index, mostra o número de registros escolhidos, menos o componente de paginação -<% will_paginate @estados %> -. Tentei mudar de posição da linha de comando na página e nada.