El presente artículo se basa en el articulo de Bala Paranj, mejor dicho es una traducción del mismo.
Me pareció muy intersante y de gran utilidad.
Pasos
Usted puede bajar el código fuente desde Paginación en Rails, que está traducido, o desde el repositorio original wpag.
Paso 1
Añada la gema al archivo Gemfile.
1 2 | gem 'will_paginate' |
Luego ejecute
1 2 | bundle |
Paso 2
Modifique el controlador de Tareas
1 2 3 4 | def index @tareas = Tarea.search(params[:term], params[:page]) end |
Paso 3
Añada el helper para vista de will_paginate en la página de vista index.
1 | <%= will_paginate @tareas %> |
Paso 4
Puede jugar en la consola de Rails para ver cómo funciona el método will_paginate:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | irb(main):002:0> t = Tarea.paginate(page: 1, per_page: 5) Tarea Load (34.6ms) SELECT "tareas".* FROM "tareas" LIMIT ? OFFSET ? [["LIM IT", 5], ["OFFSET", 0]] (6.3ms) SELECT COUNT(*) FROM "tareas" => #<ActiveRecord::Relation [#<Tarea id: 1, nombre: "Escribir un libro", created _at: "2017-07-16 18:23:50", updated_at: "2017-07-16 18:23:50">, #<Tarea id: 2, n ombre: "Comprar la batería", created_at: "2017-07-16 18:23:50", updated_at: "201 7-07-16 18:23:50">, #<Tarea id: 3, nombre: "Comprar una freidora de aire", creat ed_at: "2017-07-16 18:23:50", updated_at: "2017-07-16 18:23:50">, #<Tarea id: 4, nombre: "Comprar una casa", created_at: "2017-07-16 18:23:50", updated_at: "201 7-07-16 18:23:50">, #<Tarea id: 5, nombre: "Comprar un cachorro", created_at: "2 017-07-16 18:23:50", updated_at: "2017-07-16 18:23:50">]> irb(main):003:0> t.class => Tarea::ActiveRecord_Relation |
Podemos llamar al método de paginación con la página actual y los valores por página. Esto devuelve un objeto ActiveRelation. Podemos obtener todos los registros llamando a to_a en el objeto ActiveRelation.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | irb(main):004:0> resultado = t.to_a Tarea Load (6.1ms) SELECT "tareas".* FROM "tareas" LIMIT ? OFFSET ? [["LIMI T", 5], ["OFFSET", 0]] (5.9ms) SELECT COUNT(*) FROM "tareas" => [#<Tarea id: 1, nombre: "Escribir un libro", created_at: "2017-07-16 18:23:50 ", updated_at: "2017-07-16 18:23:50">, #<Tarea id: 2, nombre: "Comprar la baterí a", created_at: "2017-07-16 18:23:50", updated_at: "2017-07-16 18:23:50">, #<Tar ea id: 3, nombre: "Comprar una freidora de aire", created_at: "2017-07-16 18:23: 50", updated_at: "2017-07-16 18:23:50">, #<Tarea id: 4, nombre: "Comprar una cas a", created_at: "2017-07-16 18:23:50", updated_at: "2017-07-16 18:23:50">, #<Tar ea id: 5, nombre: "Comprar un cachorro", created_at: "2017-07-16 18:23:50", upda ted_at: "2017-07-16 18:23:50">] irb(main):005:0> resultado.size => 5 |
Pero hay 25 tareas
1 2 3 | irb(main):006:0> Tarea.count (7.0ms) SELECT COUNT(*) FROM "tareas" => 25 |
Podemos usar el método de página proporcionado por will_paginate para paginar las tareas
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | irb(main):067:0> t1 = Tarea.page(1).order('id DESC') Tarea Load (6.6ms) SELECT "tareas".* FROM "tareas" ORDER BY id DESC LIMIT ? OFFSET ? [["LIMIT", 11], ["OFFSET", 0]] (6.0ms) SELECT COUNT(*) FROM "tareas" => #<ActiveRecord::Relation [#<Tarea id: 25, nombre: "Leer un libro", created_at : "2017-07-16 18:23:51", updated_at: "2017-07-16 18:23:51">, #<Tarea id: 24, nom bre: "Volar sobre la isla", created_at: "2017-07-16 18:23:51", updated_at: "2017 -07-16 18:23:51">, #<Tarea id: 23, nombre: "Cortar madera para hacer fuego", cre ated_at: "2017-07-16 18:23:51", updated_at: "2017-07-16 18:23:51">, #<Tarea id: 22, nombre: "Recargar la batería", created_at: "2017-07-16 18:23:51", updated_at : "2017-07-16 18:23:51">, #<Tarea id: 21, nombre: "Obtener un corte de pelo", cr eated_at: "2017-07-16 18:23:51", updated_at: "2017-07-16 18:23:51">, #<Tarea id: 20, nombre: "Buscar bombilla de luz", created_at: "2017-07-16 18:23:51", update d_at: "2017-07-16 18:23:51">, #<Tarea id: 19, nombre: "Apague la luz", created_a t: "2017-07-16 18:23:51", updated_at: "2017-07-16 18:23:51">, #<Tarea id: 18, no mbre: "Hacer café", created_at: "2017-07-16 18:23:51", updated_at: "2017-07-16 1 8:23:51">, #<Tarea id: 17, nombre: "Vende bebida energética", created_at: "2017- 07-16 18:23:51", updated_at: "2017-07-16 18:23:51">, #<Tarea id: 16, nombre: "Co mprobar el binoculor", created_at: "2017-07-16 18:23:51", updated_at: "2017-07-1 6 18:23:51">, ...]> irb(main):068:0> t1.class => Tarea::ActiveRecord_Relation irb(main):069:0> t1r = t1.to_a Tarea Load (6.3ms) SELECT "tareas".* FROM "tareas" ORDER BY id DESC LIMIT ? OFFSET ? [["LIMIT", 30], ["OFFSET", 0]] => [#<Tarea id: 25, nombre: "Leer un libro", created_at: "2017-07-16 18:23:51", updated_at: "2017-07-16 18:23:51">, #<Tarea id: 24, nombre: "Volar sobre la isla ", created_at: "2017-07-16 18:23:51", updated_at: "2017-07-16 18:23:51">, #<Tare a id: 23, nombre: "Cortar madera para hacer fuego", created_at: "2017-07-16 18:2 3:51", updated_at: "2017-07-16 18:23:51">, #<Tarea id: 22, nombre: "Recargar la batería", created_at: "2017-07-16 18:23:51", updated_at: "2017-07-16 18:23:51">, #<Tarea id: 21, nombre: "Obtener un corte de pelo", created_at: "2017-07-16 18: 23:51", updated_at: "2017-07-16 18:23:51">, #<Tarea id: 20, nombre: "Buscar bomb illa de luz", created_at: "2017-07-16 18:23:51", updated_at: "2017-07-16 18:23:5 1">, #<Tarea id: 19, nombre: "Apague la luz", created_at: "2017-07-16 18:23:51", updated_at: "2017-07-16 18:23:51">, #<Tarea id: 18, nombre: "Hacer café", creat ed_at: "2017-07-16 18:23:51", updated_at: "2017-07-16 18:23:51">, #<Tarea id: 17 , nombre: "Vende bebida energética", created_at: "2017-07-16 18:23:51", updated_ at: "2017-07-16 18:23:51">, #<Tarea id: 16, nombre: "Comprobar el binoculor", cr eated_at: "2017-07-16 18:23:51", updated_at: "2017-07-16 18:23:51">, #<Tarea id: 15, nombre: "Montar una moto", created_at: "2017-07-16 18:23:51", updated_at: " 2017-07-16 18:23:51">, #<Tarea id: 14, nombre: "Caminar en la arena", created_at : "2017-07-16 18:23:51", updated_at: "2017-07-16 18:23:51">, #<Tarea id: 13, nom bre: "Buscar pescado", created_at: "2017-07-16 18:23:51", updated_at: "2017-07-1 6 18:23:51">, #<Tarea id: 12, nombre: "Eliminar la lista de cubos", created_at: "2017-07-16 18:23:51", updated_at: "2017-07-16 18:23:51">, #<Tarea id: 11, nombr e: "Drive a jeep", created_at: "2017-07-16 18:23:50", updated_at: "2017-07-16 18 :23:50">, #<Tarea id: 10, nombre: "Grabar un video", created_at: "2017-07-16 18: 23:50", updated_at: "2017-07-16 18:23:50">, #<Tarea id: 9, nombre: "Desarrollar una aplicación web", created_at: "2017-07-16 18:23:50", updated_at: "2017-07-16 18:23:50">, #<Tarea id: 8, nombre: "Escribir un artículo", created_at: "2017-07- 16 18:23:50", updated_at: "2017-07-16 18:23:50">, #<Tarea id: 7, nombre: "Elige el ganador", created_at: "2017-07-16 18:23:50", updated_at: "2017-07-16 18:23:50 ">, #<Tarea id: 6, nombre: "Ver una película", created_at: "2017-07-16 18:23:50" , updated_at: "2017-07-16 18:23:50">, #<Tarea id: 5, nombre: "Comprar un cachorr o", created_at: "2017-07-16 18:23:50", updated_at: "2017-07-16 18:23:50">, #<Tar ea id: 4, nombre: "Comprar una casa", created_at: "2017-07-16 18:23:50", updated _at: "2017-07-16 18:23:50">, #<Tarea id: 3, nombre: "Comprar una freidora de air e", created_at: "2017-07-16 18:23:50", updated_at: "2017-07-16 18:23:50">, #<Tar ea id: 2, nombre: "Comprar la batería", created_at: "2017-07-16 18:23:50", updat ed_at: "2017-07-16 18:23:50">, #<Tarea id: 1, nombre: "Escribir un libro", creat ed_at: "2017-07-16 18:23:50", updated_at: "2017-07-16 18:23:50">] irb(main):070:0> t1r.size => 25 |
Paso 6
Utilicemos el método de paginación proporcionado por will_paginate en el modelo de tarea.
1 2 3 4 5 6 7 | def self.search(term, page) if term where('nombre LIKE ?', "%#{term}%").paginate(page: page, per_page: 5).order('id DESC') else paginate(page: page, per_page: 5).order('id DESC') end end |
Esta paginación ahora funciona para un listado completo en el index y como resultado de búsqueda.
Paso 7
La vista index de tareas deberá lucir como el siguiente código:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | <p id="notice"><%= notice %></p> <h1>Tareas</h1> <%= form_tag(tareas_path, method: :get) do %> <%= text_field_tag :term, params[:term] %> <%= submit_tag 'Buscar', nombre: nil %> <% end %> <table> <thead> <tr> <th>Nombre</th> <th colspan="3"></th> </tr> </thead> <tbody> <% @tareas.each do |tarea| %> <tr> <td><%= tarea.nombre %></td> <td><%= link_to 'Show', tarea %></td> <td><%= link_to 'Edit', edit_tarea_path(tarea) %></td> <td><%= link_to 'Destroy', tarea, method: :delete, data: { confirm: 'Are you sure?' } %></td> </tr> <% end %> </tbody> </table> <br> <%= link_to 'New Tarea', new_tarea_path %> <%= will_paginate @tareas %> |
Paso 8
Puede personalizar la apariencia y la sensación de paginación. Copie el siguiente CSS de will_paginate a su application.css
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | .digg_pagination { background: white; cursor: default; /* self-clearing method: */ } .digg_pagination a, .digg_pagination span, .digg_pagination em { padding: 0.2em 0.5em; display: block; float: left; margin-right: 1px; } .digg_pagination .disabled { color: #999999; border: 1px solid #dddddd; } .digg_pagination .current { font-style: normal; font-weight: bold; background: #2e6ab1; color: white; border: 1px solid #2e6ab1; } .digg_pagination a { text-decoration: none; color: #105cb6; border: 1px solid #9aafe5; } .digg_pagination a:hover, .digg_pagination a:focus { color: #000033; border-color: #000033; } .digg_pagination .page_info { background: #2e6ab1; color: white; padding: 0.4em 0.6em; width: 22em; margin-bottom: 0.3em; text-align: center; } .digg_pagination .page_info b { color: #000033; background: #6aa6ed; padding: 0.1em 0.25em; } .digg_pagination:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } * html .digg_pagination { height: 1%; } *:first-child + html .digg_pagination { overflow: hidden; } .apple_pagination { background: #f1f1f1; border: 1px solid #e5e5e5; text-align: center; padding: 1em; cursor: default; } .apple_pagination a, .apple_pagination span { padding: 0.2em 0.3em; } .apple_pagination .disabled { color: #aaaaaa; } .apple_pagination .current { font-style: normal; font-weight: bold; background-color: #bebebe; display: inline-block; width: 1.4em; height: 1.4em; line-height: 1.5; -moz-border-radius: 1em; -webkit-border-radius: 1em; border-radius: 1em; text-shadow: rgba(255, 255, 255, 0.8) 1px 1px 1px; } .apple_pagination a { text-decoration: none; color: black; } .apple_pagination a:hover, .apple_pagination a:focus { text-decoration: underline; } .flickr_pagination { text-align: center; padding: 0.3em; cursor: default; } .flickr_pagination a, .flickr_pagination span, .flickr_pagination em { padding: 0.2em 0.5em; } .flickr_pagination .disabled { color: #aaaaaa; } .flickr_pagination .current { font-style: normal; font-weight: bold; color: #ff0084; } .flickr_pagination a { border: 1px solid #dddddd; color: #0063dc; text-decoration: none; } .flickr_pagination a:hover, .flickr_pagination a:focus { border-color: #003366; background: #0063dc; color: white; } .flickr_pagination .page_info { color: #aaaaaa; padding-top: 0.8em; } .flickr_pagination .previous_page, .flickr_pagination .next_page { border-width: 2px; } .flickr_pagination .previous_page { margin-right: 1em; } .flickr_pagination .next_page { margin-left: 1em; } |
Haga los cambios apropiados en el index para que tome las clases css.
1 2 3 4 5 6 | <div class="apple_pagination"> <div class="page_info"> <%= page_entries_info @tasks %> </div> <%= will_paginate @tasks, :container => false %> </div> |
Puede cambiar el aspecto de la paginación cambiando la clase a las clases definidas en el archivo application.css para flickr, apple o digg.
Resumen
En este artículo he mostrado como usar la gema will_paginate para paginar objetos ActiveRecord en Rails 5. También he mostrado como personalizar la apariencia de la paginación