Jex’s Note

Rails - 分頁 Pagination

介紹

will_paginate 如何使用

controller : posts/index

@posts = Post.includes(:user)
改成
@posts = Post.includes(:user).paginate(page: params[:page], per_page: 5)

view : posts/index

<% @posts.each do |post| %>
  <%= post.title %>
<% end %>
<%= will_paginate @posts %>

will_paginate not working

如果傳入的是 ActiveRecord_Associations_CollectionProxy 而不是 ActiveRecord_Relation 可能會造成此狀況,在 controller 要額外引入

require 'will_paginate/array'

bootstrap 樣式

view :

<%= will_paginate @posts, :renderer => PaginationLinkRenderer %>

config/initializers/pagination_link_renderer.rb :

require 'will_paginate/view_helpers/link_renderer'
require 'will_paginate/view_helpers/action_view'

class PaginationLinkRenderer < ::WillPaginate::ActionView::LinkRenderer
  protected
  def page_number(page)
    unless page == current_page
      tag(:li, link(page, page, :rel => rel_value(page)))
    else
      tag(:li, link(page, '#', :rel => rel_value(page)), :class => "active disabled")
    end
  end

  def gap
    tag(:li, link('...' , '#') , :class => "disabled")
  end

  def previous_or_next_page(page, text, classname)
    tag(:li, link(text , page || '#'), :class => page ? classname : classname + ' disabled')
  end

  def html_container(html)
    tag(:div , tag(:ul, html , container_attributes) , :class => 'pagination_label col-xs-12 center')
  end
end

小技巧 - 簡化 view 的分頁

在 controller 多指定變數給 @paginate

@users = @paginate = User.all.paginate(:page => params[:page] , :per_page => 15)

不必擔心 @users@paginate 佔兩份記憶體, 它們都指向同一個 object_id

view/layout

<%= raw(will_paginate(@paginate ,:renderer => PaginationLinkRenderer)) if @paginate %>

在 layout 放這段, 讓 renderer 覆寫掉原生的 gem (寫在 initializers 裡, 可參考本篇 bootstrap 那邊寫法), 就不用每一個 view 都要寫 will_paginate

之後只要在需要分頁的 view 直接 <%= @paginate %> 就好

其他

取得總數

@products.total_entries

Comments