Phân trang với Kaminari
Bài đăng này đã không được cập nhật trong 9 năm
Đối với việc phân trang trong một project Rails thì chúng ta thường hay sử dụng gem will_paginate, nhưng gem Kaminari cũng là 1 gem rất phổ biến. Bài viết này sẽ cho thấy sự linh hoạt trong việc phân trang của gem Kaminari.
I. Cài đặt
Thêm dòng sau vào Gemfile
sau đó bundle install
gem 'kaminari'
II. Cách sử dụng
1) Một số query cơ bản trong phân trang
page
: xác định số thứ tự trang
# Lấy ra trang thứ 2 trong list users
User.page(2)
per
: xác định số item trong một trang
# Mỗi trang có 20 users
User.page(2).per(20)
Chú ý:
Phương thức per
không được xác định trực tiếp trong models mà thông qua page
. Điều này là hoàn toàn hợp lí bởi ta không thể xác định lấy ra bao nhiêu items khi chưa xác định số thứ tự trang.
Ngoài ra, khi sử dụng thì việc thiết lập số lượng sẽ bị ghi đè lên. Muốn lấy ra tổng tất cả items ta dùng phương thức total_count
:
a = User.count # => 100
a.page(1).per(20).size # => 20
a.page(1).per(20).total_count # => 100
padding
: lấy ra một số items
User.page(2).per(20).padding(3)
padding
cũng không phải là phương thức được xác định trực tiếp từ models.
2) Tuỳ chỉnh cấu hình
- Tuỳ chỉnh chung:
Bạn có thể tuỳ chỉnh cấu hình mặc định của Kaminari. Đầu tiên chạy lệnh sau trong Terminal Commands để tạo 1 file khởi tạo cho Kaminari:
rails g kaminari:config
Trong file config/initializers/kaminari_config.rb
sẽ có:
Kaminari.configure do |config|
# config.default_per_page = 25
# config.max_per_page = nil
# config.max_pages = nil
# config.window = 4
# config.outer_window = 0
# config.left = 0
# config.right = 0
# config.page_method_name = :page
# config.param_name = :page
# config.params_on_first_page = false
end
Sau đó có thể tuỳ chỉnh bất kì giá trị mặc định nào của Kaminari trong file này.
Mô tả các tuỳ chọn:
-
config.default_per_page: Thiết lập số lượng items hiển thị trên mỗi trang
-
config.max_per_page: Thiết lập số lượng max items hiển thị trên mỗi trang
-
config.window: Thiết lập số "inner window"
(VD: config.window = 2 => First ‹ Prev ... 2 3 4 5 6 ... Next › Last » => Trang hiện tại là trang thứ 2 và có 2 trang kề trên, 2 trang kề dưới hiện ra)
- config.outer_window: Thiết lập số "outer window"
(VD: config.outer_window = 3 => 1 2 3 ...(snip)... 18 19 20 => Tổng là 20 trang, hiện ra số 3 trang đầu và 3 trang cuối)
- config.left:
(VD: config.left = 2 => 1 2 ... => hiện ra số 2 trang đầu)
- config.right:
(VD: config.right = 3 => ... 4 5 6 => hiện ra số 3 trang cuối)
-
config.page_method_name: Thay đổi tên phương thức "page" thành bất cứ tên gì.
-
config.param_name: tên params mặc định khi dùng để chỉ số trang
3) Tuỳ chỉnh cho từng Model
.paginates_per
: thiết lập lại per_page cho từng Model
class User < ActiveRecord::Base
paginates_per 50
end
.max_paginates_per
: thiết lập max per_page
class User < ActiveRecord::Base
max_paginates_per 100
end
4) Sử dụng trong Controller
- Số thứ tự trang được truyền lên qua params[:page]
@users = User.page params[:page]
5) Gọi phân trang trong View
<%= paginate @users %>
- Khi gọi phương thức
paginate
Kaminari mặc định định dạng phân trang là:
« First ‹ Prev ... 2 3 4 5 6 7 8 9 10 ... Next › Last »
6) I18n và labels
Có thể thay đổi các labels bằng cách ghi đè lên các thiết lập có sẵn của Kaminari trong file config/locales
en:
views:
pagination:
first: "« First"
last: "Last »"
previous: "‹ Prev"
next: "Next ›"
truncate: "…"
helpers:
page_entries_info:
one_page:
display_entries:
zero: "No %{entry_name} found"
one: "Displaying <b>1</b> %{entry_name}"
other: "Displaying <b>all %{count}</b> %{entry_name}"
more_pages:
display_entries: "Displaying %{entry_name} <b>%{first} - %{last}</b> of <b>%{total}</b> in total"
7) Customizing
- Chỉnh sửa paginator:
rails g kaminari:views default
Tuỳ chỉnh các partials trong app/views/kaminari/
- Để đẹp hơn có thể chỉnh sửa theme mặc định:
rails g kaminari:views THEME
Kết luận: Gem Kaminari là một gem thực sự hữu ích trong việc phân trang, chúng ta có thể sử dụng một cách dễ dàng các cấu hình mặc định hoặc tuỳ chỉnh theo ý mình.
Tài liệu tham khảo: https://github.com/amatsuda/kaminari
All rights reserved