【超かんたん】kaminariを使ってページネーションを実装しよう！

kaminariを利用してページネーションを実装します。
今回も初心者向けにレシピ投稿アプリを例に作成していきます。

#####完成イメージ
![3a9d815d3f21a22a1045e7e9b59202e2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1140333/42f471d9-1e36-1b8a-03a4-e57784af32d5.gif)

##kaminariとは
kaminariとはページネーションが簡単に実装できるGemになります。

https://github.com/kaminari/kaminari

##ページネーションの実装
####kaminariのインストール
まずは、kaminariをインストールします。

```ruby:Gemfile
gem 'kaminari'
```

```:ターミナル
bundle install
```
####ページネーションの設定
ページネーションの基本的な設定を行っていきます。

例えば、以下のようなコードがあったとします。

```ruby:app/controllers/recipes_controller.rb
class RecipesController < ApplicationController
  def index
    @recipes = Recipe.all
  end
```
こちらを[page](https://github.com/kaminari/kaminari#controllers)メソッドを使ってページネーションしていきます。

```ruby:app/controllers/recipes_controller.rb
class RecipesController < ApplicationController
  def index
    @recipes = Recipe.page(params[:page])
  end
```

ビューにページネーションを表示させたい場所に[paginate](https://github.com/kaminari/kaminari#helpers)メソッドを使います。

```erb:app/views/recipes/index.html.erb
<div class="recipes-index">
  <% @recipes.each do |recipe| %>
    <div class="recipe-contents d-flex">
      <% if recipe.images.present? %>
        <%= image_tag recipe.images[0], class: "index-img" %>
      <% else %>  
        <%= image_tag "no_image.png", class: "index-img" %>
      <% end %>
      <div class="recipe">
        <div class="recipe-title">
          <%= link_to recipe.title, recipe_path(recipe) %>
        </div>
        <div class="recipe-content">
          カテゴリー: <span class="recipe-category"><%= recipe.category.name %></span>
          所要時間: <span class="recipe-time"><%= recipe.time_required.name %></span>
        </div>
      </div>
    </div>
  <% end %>
//ここから追記
  <div class="painate">
    <%= paginate @recipes %>
  </div>
//ここまで追記
</div>
```

これでひとまずは実装完了です。
こちらをカスタマイズしていきます。

####1ページの表示件数を変えよう！
デフォルトの設定だと１ページ25件表示されるので、表示件数を変更してみましょう。
変更するには[per](https://github.com/kaminari/kaminari#the-per-scope)メソッドを使います。

[per](https://github.com/kaminari/kaminari#the-per-scope)メソッドで５件表示に変更します。

```ruby:app/controllers/recipes_controller.rb
class RecipesController < ApplicationController
  def index
    @recipes = Recipe.page(params[:page]).per(5)
  end
```
以下の画像のように表示されれば成功です。
![2ee4093add1a1caf7a912fd22a1cc5be.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1140333/a4d9b275-9903-f3cd-545d-731a246de749.png)

####見た目を変更しよう！
簡素な見た目から少しデザインをもたせます。
今回、このレシピアプリにはbootstrapを使っているのでbootstrapようにカスタマイズしていきます。
なお、bootstrapの導入については前回記事にしているので、ご覧いただけたらと思います。

https://qiita.com/mitaninjin/items/93553535483919d17a81

以下のコマンドで簡単にカスタマイズできます。

```:ターミナル
rails g kaminari:views bootstrap4
```
このコマンドを実行するとapp/viewsにkaminariフォルダとファイルが作成され編集しなくても見た目が変更されます。

以上で完成になります。
挙動を確認してみましょう。
![3a9d815d3f21a22a1045e7e9b59202e2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1140333/42f471d9-1e36-1b8a-03a4-e57784af32d5.gif)

####リファクタリング
先ほど[per](https://github.com/kaminari/kaminari#the-per-scope)メソッドを使って１ページの表示件数を変更しました。

例えば以下のように複数のページでページネーション機能を使う場合、同じ記述を何回もし少しコードも長くなってしまいます。

```ruby:app/controllers/recipes_controller.rb
class RecipesController < ApplicationController
  def index
    @recipes = Recipe.page(params[:page]).per(5)
  end

  def result
    @results = @q.result.page(params[:page]).per(5)
  end
```

どのページでも１ページの表示件数が変わらない場合はモデルに[paginates_per](https://github.com/kaminari/kaminari#configuring-default-per_page-value-for-each-model-by-paginates_per)と記述しデフォルトの値を決めます。

```ruby:app/models/recipe.rb
class Recipe < ApplicationRecord
#中略
  paginates_per 5
#以下略
end
```

コントローラーからperメソッドを削除します。

```ruby:app/controllers/recipes_controller.rb
class RecipesController < ApplicationController
  def index
    @recipes = Recipe.page(params[:page])
  end

  def result
    @results = @q.result.page(params[:page])
  end
```