Pagination mit dem b4um Generator

Pagination mit dem b4um Generator

Wenn eine Anwendung mehr Datensätze enthält, wird eine lange Liste schnell unübersichtlich. Mit dem b4um Generator lässt sich deshalb eine serverseitige Pagination zu einer bereits vorhandenen Ressource hinzufügen.
In diesem Tutorial erweitern wir unsere bestehende Product-Übersicht. Sie verwendet bereits die b4um Tabelle und die zuvor eingerichtete Suche.

Voraussetzungen

Für dieses Tutorial sollte bereits eine Product-Ressource vorhanden sein.
Unsere Produktübersicht enthält beispielsweise folgende Felder:
name:string
description:text
price:decimal
status:string
Außerdem verwenden wir bereits:
  • die b4um Tabellenansicht
  • die b4um Suche
  • mehrere vorhandene Produkte
Die Pagination kann jedoch auch unabhängig von der Suche verwendet werden und funktioniert sowohl mit Bento- als auch mit Tabellenansichten.

1. Pagination erzeugen

Der Generator wird mit dem Namen des vorhandenen Models aufgerufen:
bin/rails generate b4um:pagination Product
Standardmäßig zeigt b4um 20 Datensätze pro Seite an.
Für unser Beispiel verwenden wir bewusst nur drei Produkte pro Seite. Dadurch lässt sich die Pagination bereits mit wenigen Testdaten ausprobieren:
bin/rails generate b4um:pagination Product --per-page=3
Der Generator erstellt und verändert daraufhin die benötigten Dateien:
create  app/controllers/concerns/b4um_pagination.rb
create  app/views/shared/_pagination.html.erb
insert  app/controllers/products_controller.rb
gsub    app/controllers/products_controller.rb
append  app/views/products/index.html.erb
Damit ist die Pagination bereits in die vorhandene Produktübersicht integriert.

2. Die gemeinsame Pagination-Logik

Der Generator erstellt:
app/controllers/concerns/b4um_pagination.rb
Darin befindet sich die wiederverwendbare Pagination-Logik von b4um.
Unter anderem werden folgende Informationen berechnet:
  • aktuelle Seite
  • Datensätze pro Seite
  • Gesamtzahl der Datensätze
  • Anzahl der Seiten
  • vorherige Seite
  • nächste Seite
Die eigentlichen Datensätze werden serverseitig mit Active Record über limit und offset geladen.
Eine zusätzliche Pagination-Gem ist dafür nicht erforderlich.

3. Der ProductsController wird automatisch angepasst

Der Generator bindet zunächst das Pagination-Concern ein:
include B4umPagination
Da unsere Produktübersicht bereits die b4um Suche verwendet, sieht die index-Action anschließend so aus:
def index
  @products, @pagination = b4um_paginate(
    b4um_search(
      Product.all,
      params[:q]
    ),
    per_page: 3
  )
end
Hier ist die Reihenfolge wichtig.
Zuerst wird die Suche ausgeführt:
b4um_search(
  Product.all,
  params[:q]
)
Anschließend wird genau diese Ergebnismenge paginiert:
b4um_paginate(...)
Dadurch können Suche und Pagination miteinander kombiniert werden.
Ohne aktive Suche wird einfach die vollständige Produktliste paginiert.

4. Pagination in der View

Der Generator ergänzt am Ende von:
app/views/products/index.html.erb
automatisch das gemeinsame Pagination-Partial:
<%= render "shared/pagination", pagination: @pagination %>
Die vorhandene Tabellenansicht muss dafür nicht verändert werden.
Unsere Produktdarstellung kann beispielsweise weiterhin so aussehen:
<% if @products.any? %>
  <%= render "table", products: @products %>
<% else %>
  <section class="b4um-empty-state">
    <h2 class="b4um-empty-state__title">
      No products yet.
    </h2>

    <p class="b4um-empty-state__text">
      Create your first product to get started.
    </p>
  </section>
<% end %>

<%= render "shared/pagination", pagination: @pagination %>
Damit erscheint die Seitennavigation automatisch unterhalb der Produktliste.

5. Pagination testen

Starten wir die Anwendung:
bin/rails server
Anschließend öffnen wir:
http://localhost:3000/products
In unserem Beispiel befinden sich fünf Produkte in der Datenbank.
Da wir beim Generator
--per-page=3
angegeben haben, werden auf der ersten Seite drei Produkte angezeigt.
Die Pagination zeigt darunter die verfügbaren Seiten sowie die Navigation zur nächsten Seite an.
Beim Wechsel auf die zweite Seite ändert sich die URL beispielsweise zu:
/products?page=2
Auf Seite 2 werden nur noch die verbleibenden zwei Produkte angezeigt.
Zusätzlich erscheint die Navigation zurück zur vorherigen Seite.

6. Suche und Pagination kombinieren

Besonders praktisch ist, dass die b4um Pagination vorhandene Query-Parameter erhält.
Unsere Produkte besitzen beispielsweise alle den Status:
Verfügbar
Suchen wir nach:
verfügbar
finden wir weiterhin alle fünf Produkte.
Durch unsere Einstellung von drei Datensätzen pro Seite werden die Suchergebnisse ebenfalls auf zwei Seiten verteilt.
Auf Seite 1 erscheinen drei Treffer.
Nach einem Klick auf Next erscheinen auf Seite 2 die verbleibenden zwei Treffer.
Der Suchparameter bleibt dabei erhalten:
/products?commit=Search&page=2&q=verfügbar
Damit wird nicht die vollständige Produktliste paginiert, sondern weiterhin ausschließlich das Ergebnis der Suche.
Das zeigt gleichzeitig, dass die beiden b4um Generatoren miteinander kombiniert werden können:
b4um:search
       ↓
gefilterte Datensätze
       ↓
b4um:pagination
       ↓
aktuelle Seite
       ↓
Tabelle oder Bento-Ansicht

7. Eigene Seitengröße festlegen

Die Anzahl der Datensätze pro Seite kann bereits beim Generator festgelegt werden.
Beispielsweise:
bin/rails generate b4um:pagination Product --per-page=50
Dadurch verwendet der Controller:
per_page: 50
Ohne Angabe von --per-page verwendet b4um standardmäßig:
20

Was der Pagination-Generator übernimmt

Mit einem einzigen Generator-Aufruf richtet b4um die wesentlichen Bestandteile der Pagination ein:
  • serverseitige Pagination
  • Active Record limit und offset
  • Previous- und Next-Navigation
  • nummerierte Seitennavigation
  • Erhaltung vorhandener Query-Parameter
  • Unterstützung für b4um Bento
  • Unterstützung für b4um Tabellen
  • Kombination mit der b4um Suche
  • sichere Behandlung ungültiger oder zu großer Seitennummern
  • gemeinsame wiederverwendbare Pagination-Logik
Eine zusätzliche Pagination-Gem wird nicht benötigt.

Ergebnis

Unsere Produktübersicht besitzt jetzt drei Funktionen, die miteinander kombiniert werden können:
Tabelle
bin/rails generate b4um:table Product name:string description:text price:decimal status:string
Suche
bin/rails generate b4um:search Product
Pagination
bin/rails generate b4um:pagination Product --per-page=3
Damit können auch größere Datenmengen übersichtlich dargestellt, durchsucht und auf mehrere Seiten verteilt werden.
Im nächsten Schritt können wir die klassische Seitennavigation durch Infinite Scroll ersetzen. Dabei werden weitere Datensätze automatisch geladen, sobald der Benutzer nach unten scrollt.

Meld dich an und schreibe ein Kommentar