Rail+Senna(Tritonn)全文検索結果をwill_paginateでページネーションする。

通常、Modelのfindメソッドの代わりにpaginateメソッドを使用すれば良いのだが、全文検索の場合は独自メソッドを呼び出すため上手くいかない。

とりあえずmislav-will_paginateのRdoc(...gems/1.8/doc/mislav-will_paginate-2.3.2/rdoc/index.html)を見ると、
Model.paginateメソッドではWillPaginate::Collectionを返すので、Controller内でWillPaginate::Collectionを生成すれば良い模様。

前エントリで作成したViewとControllerを差し替えてみる。

View
#●search.html.erb
<% form_tag({:action => "search"}, {:method => "get"}) do %>
  <%= text_field_tag "q", @q, :class => "query" %>
  <%= submit_tag "検索" %>
<% end %>
<table border="1">
  <tr>
    <th>id</th>
    <th>名前</th>
    <th>住所</th>
  </tr>
  <% @users.each{|m| %>
  <tr>
    <td><%= m.id %></td>
    <td><%= m.name %></td>
    <td><%= m.address %></td>
  </tr>
  <% } %>
</table>
# ↓追加
「<%= @q %>」の検索結果 <%= @users.total_entries %>件
<% p=(@q || "").empty? ? nil : {:q => params[:q]} %>
<%= will_paginate(@users, :params => p) %>
Controller
#●user_controller.rb
class UserController < ApplicationController
  def index
  end

  def search
    @q = params[:q]
    query = {:name => @q, :address => @q}

    # 表示するページ&1ページ当たり件数を設定
    page = params[:page] ? params[:page] : 1
    per_page = 10

    # 検索結果をもとにWillPaginate::Collectionを生成
    @users = WillPaginate::Collection.create(page, per_page) do |pager|
      result = User.find_fulltext(query, :all => true, :limit => pager.per_page, :offset => pager.offset)
      pager.replace(result)
      unless pager.total_entries
        pager.total_entries = User.count_fulltext(query, :all => true) # 検索トータル数を設定
      end
    end
  end
end

これでページネーションもOK。