【ページネーション】
1ページあたり20件に設定。
スタイルはBootstrap4で実装します。
【検索機能】
投稿一覧から検索とブックマーク済み投稿一覧から検索の2パターン実装していきます。
検索条件はタイトルか本文の部分一致とします。
【事前準備】
・ブックマーク機能を実装しておいてください。
参考資料:【Rails】ブックマーク(お気に入り)機能
・bootstrap4を使用できるように設定しておいてください。
参考資料:BootstrapをRailsに導入してみよう!徹底解説!
環境
Rails 5.2.3
mysql 5.7.28
gem kaminari
gem ransack
実装
それでは実装していきます。
gemの追加
gem kaminari
gem ransack
Gemfileに追加し、bundle install
gem 'kaminari'
gem 'ransack'
$ bundle install
ページネーション実装
まずはページネーションから実装していきます。
ターミナルでkaminari
の設定ファイルを自動生成するコマンドを入力します。
$ rails g kaminari:config
これでkaminari
の動作を変えるために必要な設定ファイルを生成できます。
次にページネーション用のビューファイルをを自動生成するコマンドを入力します。
$ rails g kaminari:views bootstrap4
これでbootstrap4のページネーションのデザインに合わせたビューファイルが自動で生成されます。
次に1ページあたりのデータ取得数を書き換えます。
デフォルトでは25件のデータを取得する設定になっています。
# frozen_string_literal: true
Kaminari.configure do |config|
config.default_per_page = 20 # 25から20に書き換え
# config.max_per_page = nil
# config.window = 4
# config.outer_window = 0
# config.left = 0
# config.right = 0
# config.page_method_name = :page
# config.param_name = :page
# config.params_on_first_page = false
end
次はコントローラーにpageメソッドを追加していきます。
def index
@boards = Board.includes(:user).page(params[:page])
end
def bookmarks
@boards = current_user.bookmark_boards.includes(:user).page(params[:page])
end
kaminari
をインストールしたことでモデルクラスに対してpageメソッド
が使用できるようになります。
先ほど設定した1ページあたりのデータ取得件数を引数のparams[:page]
に格納し、ビューで表示するようにします。
この時点で1ページ目には20件のデータが表示されているはずです。
2ページ目以降も見れるようにリンクを貼ります。
リンクを貼りたい箇所に<%= paginate @boards %>
を記述すればOKです。
サーバーを再起動して、このようなリンクが表示されていれば実装完了です。
日本語化
実装は完了ですが英語の部分を日本語化しておきます。
デフォルトのロケール(言語)を日本語にします。
module アプリ名
class Application < Rails::Application
# 追記↓
config.i18n.default_locale = :ja
次に日本語訳を設定するファイルを作成・記述していきます。
config/locales/ja.yml
を作成し任意の日本語を記述していきます。
ja:
views:
pagination:
first: 最初
last: 最後
previous: 前
next: 次
truncate: ...
これで設定が完了したのでサーバーを再起動したら反映されているはずです。
検索機能実装
controllerを編集
def index
@q = Board.ransack(params[:q]) # 検索オブジェクト作成
@boards = @q.result.includes(:user).page(params[:page]) # 検索結果(検索しなければ全件取得)
end
def bookmarks
@q = current_user.bookmark_boards.ransack(params[:q]) # 検索オブジェクト作成
@boards = @q.result.includes(:user).page(params[:page]) # 検索結果(検索しなければ全件取得
end
viewを編集(検索フォーム)
<!-- 検索フォーム -->
<%= render 'search_form', url: boards_path, q: @q %>
<!-- 検索フォーム -->
<%= render 'search_form', url: bookmarks_boards_path, q: @q %>
<%= search_form_for q, url: url do |f| %>
<div class="input-group mb-3">
<%= f.search_field :title_or_body_cont, class: "form-control", placeholder: '検索ワード' %>
<div class="input-group-append">
<%= f.submit "検索", class: "btn btn-primary" %>
</div>
</div>
<% end %>
<%= search_form_for q, url: url do |f| %>
のurlを一覧とブックマーク一覧のurlで指定することでその範囲内から検索をすることができます。
<%= f.search_field :title_or_body_cont,...
でtitleカラムとbodyカラムのどちらからでも検索が部分的に一致すれば表示されます。
条件はこちらのサイトを参考にしました。
Ransackで簡単に検索フォームを作る73のレシピ
viewを編集(検索結果一覧)
<!-- 掲示板一覧 -->
<% if @boards.any? %>
<div class="row d-flex">
<%= render @boards %>
</div>
<% else %>
<h1><%= '検索結果がありません。' %></h1>
<% end %>
<%= paginate @boards %>
これでインスタンスにデータが存在すれば一覧表示され、なければ検索結果がありませんと表示されます。
まとめ
わりとすんなり実装できたかなと思います。
詰まったとことしては検索範囲を全boardとbookmark_boardで範囲分けする部分でしたが、urlを検索範囲に指定することで解決しました。