kaminariではないバニラなページネーションをやっていく

# 経緯
- kaminariでやれば良いものをなんか意地はりました。
- [Ruby on Rails 5 アプリケーションプログラミング](https://www.amazon.co.jp/Ruby-Rails-5%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-%E5%B1%B1%E7%94%B0-%E7%A5%A5%E5%AF%9B/dp/4774188832/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=Ruby+on+Rails+5%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0&qid=1555163469&s=books&sr=1-1)を読んでいたのですが、limitメソッドとoffsetメソッドを使えばページネーションができると書いてあり、やってみようとしました。

# 目標形
- 数字リンク部分は常時3つ表示されるようにする。

（以下、例として総ページ数が5の場合。{}はアクティブな状態）

1. 初回遷移時（1を押下した時）
  - {1}[2][3][>][≫]
2. 2を押下した時
  - [<]{2}[3][4][>][≫]
3. 3を押下した時
  - [≪][<]{3}[4][5][>]
4. 4を押下した時
  - [≪][<][3]{4}[5][>]
5. 5を押下した時
  - [≪][<][3][4]{5}


※こんなイメージ（初回遷移時）
![名称未設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283730/83f75f9d-35be-8227-1e4a-8bd2ea520de7.png)


# 実装

```games_controller.rb
  GAME_SIZE_PER_PAGE = 15

  def index
    @current = params[:page].nil? ? 1 : params[:page].to_i

    @games = Game.all.limit(GAME_SIZE_PER_PAGE).offset(GAME_SIZE_PER_PAGE * (@current - 1))
    @max_page = (Game.all.size.to_f / GAME_SIZE_PER_PAGE).ceil

    @pagination = {}
    @pagination['≪'] = 1 if @current >= 3
    @pagination['<'] = @current - 1 if @current != 1

    if @current + 2 >= @max_page
      @pagination.merge!({@max_page - 2 => @max_page - 2, @max_page - 1 => @max_page - 1, @max_page => @max_page})
      delete_list = [0, -1]
      @pagination.delete_if do |key, value|
        delete_list.include?(value)
      end
    else
      @pagination.merge!({@current => @current, @current + 1 => @current + 1, @current + 2 => @current + 2})
    end

    @pagination['>'] = @current + 1 if @current != @max_page
    @pagination['≫'] = @max_page if @current <= @max_page - 3

  end
```

```index.html.erb
※Bootstrap4の記述も入っている。
  <ul class="pagination justify-content-center">

    <% @pagination.each do |key, value| %>
      <li class="page-item<%= ' active' if value == @current %>">
        <%= link_to key, games_path(page: value), class: 'page-link' %>
      </li>
    <% end %>

  </ul>
```


# ポイント
- 総ページ数を求めるロジック
  - 要素をページあたりの表示数で割って、総ページ数を求めるが、割ったあまりの分もページを用意する必要があるため、ceilメソッドを使って切り上げる。

```rb
@max_page = (Game.all.size.to_f / GAME_SIZE_PER_PAGE).ceil
```

- 0ページ目と-1ページ目が発生していたら削除
  - 目標形でいう「4以降を押下した時」は、押下されたリンクを左端に置かずに、[3][4][5]が常に表示されるようにするため、このようなロジックを組んでいる。ただ、これだと0ページ目と-1ページ目が発生する場合がある（例えば総ページ数が1しかない場合など）ため、削除する処理を入れる。

```rb
@pagination.merge!({@max_page - 2 => @max_page - 2, @max_page - 1 => @max_page - 1, @max_page => @max_page})
delete_list = [0, -1]
@pagination.delete_if do |key, value|
   delete_list.include?(value)
end
```

- pathヘルパーに引数を与えると、クエリパラメータになる
  - どのリンクが押下されたかをクエリパラメータでコントローラーまで運ぶ。この書き方を知らなかったため、個人的には今回一番の学びポイントになった。

```
<% @pagination.each do |key, value| %>
    <li class="page-item<%= ' active' if value == @current %>">
      <%= link_to key, games_path(page: value), class: 'page-link' %>
    </li>
<% end %>
```

# 参考
- [Railsでkaminariを使わずにシンプルなページング処理を自作する](https://qiita.com/knt45/items/8ed3e9f77509ecc6a69d)
- [link_toのpathにGETパラメータを付与](http://net-vacation.com/ruby-on-rails/add-params-link_to)
- [Ruby on Rails 5 アプリケーションプログラミング](https://www.amazon.co.jp/Ruby-Rails-5%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-%E5%B1%B1%E7%94%B0-%E7%A5%A5%E5%AF%9B/dp/4774188832/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=Ruby+on+Rails+5%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0&qid=1555163469&s=books&sr=1-1)