乐者为王

Do one thing, and do it well.

使用will_paginate插件给Rails应用添加分页功能

安装will_paginate插件:

1
script/plugin install git://github.com/mislav/will_paginate.git

安裝好插件后,在action中將本來的find方法:

1
@contacts = Contact.all

改为

1
@contacts = Contact.paginate(:page => params[:page])

然后在action对应的view最后加入以下代码:

1
<%= will_paginate @contacts %>

现在便可以使用分页功能了,该语句会产生如下的HTML代码:

1
2
3
4
5
6
<div class="pagination">
  <span class="disabled prev_page">« Previous</span>
  <span class="current">1</span>
  <a href="/contacts?page=2&s=" rel="next">2</a>
  <a href="/contacts?page=2&s=" class="next_page" rel="next">Next »</a>
</div>

下面加入搜索功能,在view的适当位置加入:

1
2
3
4
5
6
<% form_tag contacts_path, :method => 'get' do %>
<p>
  <%= text_field_tag :s, params[:s] %>
  <%= submit_tag "Search", :name => nil %>
</p>
<% end %>

并且将action中的代码修改为:

1
2
3
@contacts = Contact.paginate(
  :page => params[:page],
  :conditions => ["name like ?", "%#{params[:s]}%"])

试着进行搜索,可以看到搜索结果也很好的进行了分页。

此外will_paginate还提供一些分页统计信息:

1
2
3
Total entries: <%= @contacts.total_entries %>
Total pages: <%= @contacts.total_pages %>
Current page: <%= @contacts.current_page %>

最后加上will_paginate推荐的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
.pagination {
  padding: 3px;
  margin: 3px;
}

.pagination a {
  padding: 2px 5px 2px 5px;
  margin: 2px;
  border: 1px solid #aaaadd;
  text-decoration: none;
  color: #000099;
}

.pagination a:hover, .pagination a:active {
  border: 1px solid #000099;
  color: #000;
}

.pagination span.current {
  padding: 2px 5px 2px 5px;
  margin: 2px;
  border: 1px solid #000099;
  font-weight: bold;
  background-color: #000099;
  color: #fff;
}

.pagination span.disabled {
  padding: 2px 5px 2px 5px;
  margin: 2px;
  border: 1px solid #eee;
  color: #ddd;
}

在写代码的时候碰到一个问题,网上的文章都使用page_count来表示总的分页数,但我在使用时出现了undefined method 'page_count'错误,把page_count换成total_pages后就好了。

2011/1/4更新

这里使用的是2.3.12版本的will_paginate,暂时还不支持i18n,不过可以通过在app/helps/application_helper.rb中添加以下代码来实现:

1
2
3
4
5
6
7
8
9
include WillPaginate::ViewHelpers

def will_paginate_with_i18n(collection, options = {})
  will_paginate_without_i18n(collection, options.merge(
                        :previous_label => I18n.t(:previous, :default => 'Previous'),
                        :next_label => I18n.t(:next), :default => 'Next'))
  end

alias_method_chain :will_paginate, :i18n

然后在config/locales/zh.yml中添加:

1
2
previous: "« 前一页"
next: "后一页 »"

Comments