読者です 読者をやめる 読者になる 読者になる

spring of life

技術、ときどき日常のブログ(予定)

ページネーションの ajax 対応

Rails

kaminari の ajax 対応にかなり時間かかった。。。

いわゆるページネーションのリンクをクリックしたら(例えば)次のリソース一覧が表示される、とかじゃなくて

ページ上部にリソース登録画面があって、submit ボタン押したらリソース一覧とページネーションのリンクが非同期で更新される

という感じに実装したかった


ちなみに、何作ってるかというと、家計簿を管理するアプリです。完全に自分用ですが。。。

というか作ったのは勉強のためっていうのが大きいかな

今度改めてちゃんと書いとこうっと。まだ他にもアプリ作ってるし

リソース一覧の更新

これは楽勝だった

家計簿を表示する部分テンプレートを用意しといて、それを描画するだけ

accounts_controller.rb

  • WebAPI として使われる場合もあるので、その場合はformat.jsonで処理
  • ajax の場合は js なので家計簿を取得して後で使う変数に代入
def create
  ...
  @account = Account.create!(accounts)
  ...
  respond_to do |format|
    format.json { render :status => :created }
    format.js { @accounts = Account.order(:date => :desc).page(params[:page]) }
  end
  ...
end

accounts.html.erb

  • テーブルのデータ(ヘッダ以外)だけ更新したいので、<tbody>にidをつけて更新
...
<tbody id="accounts">
  <%= render 'account' %>
</tbody>
...

create.js.erb

  • 部分テンプレートを再描画
$('#accounts').html("<%= j(render 'account') %>");

_account.html.erb

<% @accounts.each do |account| %>
<tr>
  <td><%= account.date %></td>
  ...
</tr>
<% end %>

ページネーション部分の更新

これの挙動がさっぱり分からなくて、とりあえず解決したけどまだあまり納得してない。。。

とりあえず↓のように書いたんだけどダメだった

accounts.html.erb

...
<div id="pagination">
  <%= paginate @accounts %>
</div>
...

create.js.erb

  • 再描画時に家計簿一覧と同時に更新
$('#accounts').html("<%= j(render 'account') %>");
$('#pagination').html("<%= j(paginate @accounts) %>");

まぁ、ブラウザにはちゃんとリンクが表示されるんだけども、そのリンク先が意味わからない(´Д` )

create のパスになってて、登録した家計簿のフォームデータがクエリになってついてたんだよね。。。

で、いろいろ調べたんだけど、コントローラーやアクションを変えれるようで

create.js.erb

$('#accounts').html("<%= j(render 'account') %>");
$('#pagination').html("<%= j(paginate @accounts, {:params => {:action => 'hogehoge’}}) %>");

とかいう感じでparamsにcontrollerとかactionとか指定すればいいっぽい

で、これでリンクをクリックしたら次のページとかに飛ぶようになったんだけど、クエリは変わらず付いたまま(´・_・`)

どうしようかな〜と悩んだ末、paramsに消したいクエリのキーも追加するようにした

create.js.erb

$('#accounts').html("<%= j(render 'account') %>");
$('#pagination').html("<%= j(paginate @accounts, {:params => {:action => 'hogehoge’, :accounts => {}}}) %>");

とかいう感じで空ハッシュを指定すると消えるので。

この解決方法がいいのかよく分からんけど、これで見た感じの問題はなくなったかな〜

create のパスになってるのはなんとなく分かるけど、POSTで登録したのがなんでクエリになって付くんだろ。。

kaminari のソースコード読まないとダメかな(^_^;)