<%= paginate @users.hogehoge %>
上記のコードを見た私「うーむわからん」
Rails でページネーションを実装する際に使われるでおなじみの kaminari ですが、それについてわからないことがあったのでまとめます。
基本的な kaminari でのページネーション
上記を見てもらうと詳細な実装の仕方がわかるのですが
views/users/index.html.erb
<%= paginate @users %>
基本的には上記のような感じ
今回のシチュエーション
今回私が遭遇したシチュエーションでは
Users コントローラーの index では別クラスの UserDetail モデルを new している
という状況でした。具体的には
users_controller.rb
@users = UserDetail.new(User.all.page(params[:page]).per(10), user_detail_params)
みたいな感じです。
UserDetail モデルでは
user_detail.rb
def initialize(users, attributes)
@users = users.preload(:order)
super(attributes)
end
みたいな感じでした。
コントローラーで定義しているインスタンス変数に対して、kaminari の paginate を使用すると
「total_pagesメソッドが定義されていませんよ」
というエラーがでる。
kaminariのページネーションのViewをActiveRecord以外のオレオレオブジェクトで実現する方法
上記のサイトに、詳しい理屈などを日本語で書いてくださっていたので助かりました。
で、具体的には何が問題なのかというと
・paginate はアクティブレコード由来のオブジェクトに対して total_page を含めたメソッドを使用する
・現在のコードでは Users コントローラーのインスタンス変数で User モデルのほうに paginate が参照しに行っているからエラーがでる?のかな?(間違っていたらすみません)
なので UserDetail モデルで定義した変数(initialize で定義している @users)と view から現在のページ数を受け取ってそれを返す変数(コントローラーで定義している @users)の二つが必要ってことになります。
別のモデルで定義した変数を view では使用できないので
user_detail.rb
def hogehoge
@users
end
みたいな感じで定義してやって
views/users/index.html.erb
<%= paginate @users.hogehoge %>
こんな感じで、コントローラーで定義しているインスタンス変数に対して、クラスで変数を定義したメソッドを適用してあげると大丈夫!という話ですわ。
別解
user_detail.rb
def total_pages
@users.total_pages
end
def current_page
@users.current_page
end
def limit_value
@users.limit_value
end
上記のように、モデルオブジェクトに対して、paginate が期待する3つのメソッドをあらかじめ使用していると
views/users/index.html.erb
<%= paginate @users %>
のみでも問題なく動きます。
コードの総数は最初の解法のほうが少ないけど、別解のほうがわかりやすくはありますよね。悩ましいところです。
以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上以上!!!!