はじめに
ページネーションを実装する時にkaminariを使用することが多いと思います。
しかし、その前に取得したレコードを操作して配列になっていたりすると、そのまま.page(params[:page])
を適用させることはできません。
このようなケースが個人開発であったのですが、応用的な使い方を知らず少々つまずいたので、今回記事に残しておくことにしました。
やりたいこと
- Itemモデル全体をシャッフルして表示する
- 表示は、ページネーション対応で1ページに5個までにする
- kaminariのインストールはこちらが参考になります
開発環境
Ruby 3.1.2
Rails 6.1.6
実装
そもそもページネーションを適用しないのであれば、shuffleメソッドを使用するだけで完了します。
...
def index
@items = Item.all.shuffle
end
...
ここで、Item.all.shuffle
後ろに.page(params[:page])
を加えれば良いのではないかと思いますが、これをするとNoMethodError
をはかれてしまいます。
なぜかというと、クラスの違いによるものです。
Item.all
と Item.all.shuffle
のクラスをコンソールで見てみましょう。
> Item.all.class
=> Item::ActiveRecord_Relation
> Item.all.shuffle.class
=> Array
このように、shuffle
メソッドを使用すると、クラスがArray(配列)になってしまうのです。そして、.page(params[:page])
は、配列には使用することができないため、エラーが発生してしまっていました。
では、これを解決する方法は何なのかというと、kaminari側で配列にも対応できるメソッドを用意してくれています。
それは、paginate_array
メソッドです。(GitHubのリンクを示しておきます。)
...
def index
@items = Kaminari.paginate_array(Item.all.shuffle).page(params[:page]).per(5)
end
...
Kaminari.paginate_array(Item.all.shuffle)
を前につけるだけで、配列にも対応できるようになりました。
余談ですが、viewファイルに<%= paginate インスタンス変数 %>
を記述するのを忘れないようにしてくださいね。
さいごに
まさかkaminari側でこのような場合にも対応できるようにしてくれているなんて、驚きました…
どなたかのお役に立てれば幸いです。