Railsアプリケーションに検索機能を実装する手順についてまとめました。
ここではユーザー一覧の画面でユーザー名を検索して絞り込みを行う機能を説明していきます。
Ransackインストール
gimfile追記
Ransackが定番のようですのでこれを使用していきます。Gemfileに追記します。
gem 'ransack'
インストール
$ bundle install
コントローラーにindexアクションを定義
今回はユーザー名(name)を検索する機能を実装します。READMEに従って書いていきます。
app/controllers/users_controller.rb
class UsersController < ApplicationController
.
.
def index
@q = User.ransack(params[:q])
@users = @q.result(distinct: true).order(name: :asc).page(params[:page])
end
.
.
end
ransackに渡すパラメーターは:q
が使用されています。これをモデル(今回はUser)に渡して@q = モデル名.ransack(params[:q])
のように定義します。
次の行で検索結果として表示するデータを(今回は@usersで)定義します。
distinct: true
で重複データがまとまります。投稿内容からユーザーを検索する場合などで使用すると、同一ユーザーで複数の投稿それぞれで検索がヒットしても同じユーザーが複数表示されないようになります。今回distinctはつけていなくても問題なさそうです。
もとは以下のようにUser全件+ページネーションになっていました。ページネーション実装前は@users = User.all
でした。
class UsersController < ApplicationController
.
.
# 検索機能実装前
def index
@users = User.order(name: :asc).page(params[:page])
end
.
.
end
Ransackはデフォルトで全件表示になっているようですので、そのまま上書きでOKでした。
ビューに検索フォームを追加
ユーザー一覧のビューに検索フォームを追加していきます。
READMEにある一番シンプルな例が以下です。
<%= search_form_for @q do |f| %>
# nameに含まれているか検索
<%= f.label :name_cont %>
<%= f.search_field :name_cont %>
<%= f.submit %>
<% end %>
どの属性で検索するかを:name_cont
のように"属性"+"_cont"で指定しています。contは含む(contain)ですが、他にも◯◯で始まる(_start)など色々あります。
検索フォームのパーシャル作成
検索フォームは他でも使えるようにパーシャルで作成していきます。
app/views/users/_search_form.html.erb
<%= search_form_for @q do |f| %>
<%= f.search_field :name_cont, placeholder: "ユーザー名を検索...", class: "form-control" %>
<%= f.submit "検索", class: "btn btn-primary" %>
<% end %>
今回はラベルは表示しないように<%= f.label :name_cont %>
は省略しました。その代わりにplaceholder: "ユーザー名を検索…"
で検索フォームの中に何を検索するか書いています。
CSSはBootstrapを使用しています。
検索フォームをビューに追加
作成したパーシャルをビューに追加します。
app/views/users/index.html.erb
.
.
<%= render 'search_form' %>
.
.
完成
↑こんな感じになりました。
Tweet