Nivel inicial5 min de lectura · Publicado el

Paginación en Ruby on Rails con will_paginate y Pagy

Paginación en Ruby on Rails: un libro con páginas de 10 artículos (per_page: 10) y la página 2 pedida en la URL /articles?page=2 Miles de filas, 10 por hojarubentejera.com 12/articles?page=2per_page: 10
Como en un libro, el listado no cabe en una hoja y se reparte en páginas de 10 artículos (per_page: 10). El número de página viaja en la URL, /articles?page=2, y la base de datos solo devuelve esos 10.

Tu listado de artículos empieza con diez y acaba con miles. Cargarlos todos en una página la hace lenta y nadie va a leerla entera.

Paginar es como un libro: el texto completo no cabe en una hoja, así que se reparte en páginas numeradas y el lector salta a la que quiere. En la web, el número de página viaja en la URL (?page=2) y la base de datos solo devuelve los registros de esa página.

Paginación con will_paginate en tres pasos

  1. Añade la gema.
  2. Pagina la consulta en el controlador.
  3. Pinta los enlaces de página en la vista.

1. Añade la gema

En el Gemfile:

gem "will_paginate", "~> 4.0"

Y la instalas:

bundle install

2. Pagina en el controlador

# app/controllers/articles_controller.rb
def index
  @articles = Article.publicados.ultimos.paginate(page: params[:page], per_page: 10)
end
  • page es la página que pide el usuario. Llega en la URL: http://localhost:3000/articles?page=2. Si no viene, se muestra la primera.
  • per_page es cuántos registros hay por página. Por defecto son 30.
  • publicados y ultimos son scopes, consultas con nombre definidas en el modelo. Puedes encadenar paginate antes o después de ellos. Tienes más en Scopes en Ruby on Rails.

Si quieres el mismo tamaño en todo el modelo, fíjalo una vez:

class Article < ApplicationRecord
  self.per_page = 10
end

3. Pinta la paginación en la vista

<%# app/views/articles/index.html.erb %>
<% @articles.each do |article| %>
  <h2><%= link_to article.title, article %></h2>
  <div><%= article.body %></div>
<% end %>

<%= will_paginate @articles %>

will_paginate @articles genera solo los enlaces «anterior», los números de página y «siguiente»:

Controles de paginación generados por will_paginate bajo un artículo de prueba: Previous, las páginas 1 y 2, y Next

Salen sin estilos; el README de la gema enlaza unas hojas CSS de ejemplo para darles forma. Si dudas entre <% %> y <%= %> en la vista, lo tienes en Diferencia entre <% %> y <%= %> en Ruby on Rails.

Alternativas actuales: Pagy y Kaminari

Pagy

Pagy tiene desarrollo activo (la serie 43; aquí se ha probado la 43.8.1, de octubre de 2026) y destaca por ser ligera. La idea es la misma, con otra sintaxis:

# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  include Pagy::Method
end

# app/controllers/articles_controller.rb
def index
  @pagy, @articles = pagy(:offset, Article.publicados.ultimos, limit: 10)
end
<%# app/views/articles/index.html.erb %>
<%== @pagy.series_nav %>

pagy devuelve dos cosas: el objeto con los datos de la paginación (@pagy) y los registros de la página (@articles). series_nav pinta los enlaces; va con <%== %> porque ya devuelve HTML seguro.

series_nav genera un <nav> con enlaces «anterior», números y «siguiente», y marca la página actual con aria-current="page".

Kaminari

Kaminari es la otra gema clásica de paginación en Rails y sigue publicando versiones (la 1.3.3 salió en noviembre de 2026). Su sintaxis encadena métodos:

# Gemfile
gem "kaminari"

# app/controllers/articles_controller.rb
@articles = Article.publicados.ultimos.page(params[:page]).per(10)
<%= paginate @articles %>

No mezcles Kaminari y will_paginate en el mismo proyecto: los dos añaden un método page a los modelos y chocan.

Resumen

Paso will_paginate Pagy 43 Kaminari
Gema gem "will_paginate" gem "pagy" gem "kaminari"
Controlador Article.paginate(page: params[:page], per_page: 10) @pagy, @articles = pagy(:offset, Article.all, limit: 10) Article.page(params[:page]).per(10)
Vista <%= will_paginate @articles %> <%== @pagy.series_nav %> <%= paginate @articles %>
Estado Modo mantenimiento Desarrollo activo Desarrollo activo

Fuentes

  • README de will_paginate (versión 4.0.1): uso de paginate, per_page y aviso de modo mantenimiento.
  • Documentación de Pagy y su README (serie 43; probado con la 43.8.1).
  • README de Kaminari y versión 1.3.3 en RubyGems.
  • Ejecutado en Docker con la imagen oficial ruby:4.0 (Ruby 4.0.9), Active Record 8.1.4.1 y SQLite en memoria, con 5 registros y 2 por página: paginate con scopes (will_paginate 4.0.1, per_page por defecto 30), page(2).per(2) (Kaminari 1.3.3, en un script aparte porque choca con will_paginate) y pagy(:offset, …, limit: 2) con el HTML de series_nav (Pagy 43.8.1). Los helpers de vista will_paginate y paginate solo se han comprobado en sus README. La captura es de Rubén, del artículo original.