Pagination

現在要來建立分頁,使用 will_paginate gem,同時也要安裝 bootstrap-will_paginate gem ,用來設定樣式:

source 'https://rubygems.org'

gem 'rails',                   '4.2.2'
gem 'bcrypt',                  '3.1.7'
gem 'faker',                   '1.4.2'
gem 'will_paginate',           '3.0.7'
gem 'bootstrap-will_paginate', '0.0.10'
.
.
.

執行 bundle

$ bundle install

重啟 Rails server 確保 gem 有被正確載入。

接著在要在 index view 撰寫分頁架構,還要在 index action 使用一個物件來取代 User.all

在 view 裡使用了 will_paginate 方法:

app/views/users/index.html.erb

<% provide(:title, 'All users') %>
<h1>All users</h1>

<%= will_paginate %>

<ul class="users">
  <% @users.each do |user| %>
    <li>
      <%= gravatar_for user, size: 50 %>
      <%= link_to user.name, user %>
    </li>
  <% end %>
</ul>

<%= will_paginate %>

users view 裡面,透過 will_paginate 方法,會自動去尋找 @users 物件,然後顯示分頁連結。目前分頁還無法作用,因為此刻的 @users 等於 User.all。而 will_paginate 需要使用 paginate 才會顯示分頁:

$ rails console
>> User.paginate(page: 1)
  User Load (1.5ms)  SELECT "users".* FROM "users" LIMIT 30 OFFSET 0
   (1.7ms)  SELECT COUNT(*) FROM "users"
=> #<ActiveRecord::Relation [#<User id: 1,...

paginate 方法接受一個 hash 參數,key 是 :page,value 就是第幾頁。基於 :page 的 value, User.paginate 會從資料庫裡一次取出相對應的使用者筆數(預設是 30 筆),例如,第一頁會有 1-30 筆,第二頁有 31-60 筆,以此類推。如果 :pagenilpaginate 會返回第一頁。

所以在 index action 裡,我們要使用 paginate 代替 all,這邊 :page 的參數來自於 params[:page],這是由 will_paginate 自動產生:

app/controllers/users_controller.rb

class UsersController < ApplicationController
  before_action :logged_in_user, only: [:index, :edit, :update]
  .
  .
  .
  def index
    @users = User.paginate(page: params[:page])
  end
  .
  .
  .
end

現在分頁應該能正常運作:

如果點擊第二頁,就會顯示第二頁: