Ransackを使って検索機能を実装
69日目です。
個人アプリにRansackを使って検索機能を実装したのですが、思いの外大変だったので残します。
Ransackとは
検索機能を実装してくれるgem。ユーザーの名前だけなどでなく、様々な検索方法が可能になるとのこと。
実装したアプリ
実装の流れ
Gemfileにファイル名を記述
gem 'ransack'
ターミナルでbundle install
ローカルサーバー再起動
posts/index.html.erbにusers/index.html.erb(ユーザー検索ページ)へのリンクを追記
<div class="contents row back"> <% @posts.each do |post| %> <%= render partial: "post", locals: { post: post } %> <% end %> <%= paginate(@posts) %> <%= link_to "ユーザー検索", "/posts/:post_id/users" %> # この行を追記 </div>
users_controller.rbにindexアクションを追記
def index @search = User.ransack(params[:q]) @users = @search.result end
users/index.html.erb(ユーザー検索ページ)を作成
<%= search_form_for @search, enforce_utf8: false do |f| %> <%= f.label :name_cont, "ユーザー名"%> <%= f.search_field :name_cont %> <div class="actions"><%= f.submit "検索" %></div> <% end %> <% if request.url.match(/commit/)%> <% @users.each do |user| %> <p><%= user.id %></p> <p><%= link_to "#{ user.name}", "users/#{user.id}" %></p> <% end %> <% end %>
ransackを使うことで「search_form_for」というメソッドが使えるようになります。
検索結果のところで条件分岐を書かないと、検索する前から候補一覧が表示されてしまいます。
そのため、もしURLに「commit」が含まれていれば検索結果を表示するという条件分岐にしています。
また検索結果の名前を押したら、そのユーザーのマイページに飛べるようリンクにしています。
躓いたところ
「No Ransack::Search object was provided to search_form_for!」(Ransack :: Searchオブジェクトがsearch_form_forに提供されていません)
というエラーが発生しました。
調べても検討がつかなかったため、初めてteratailで質問させて頂きました。
Ruby - 「No Ransack::Search object was provided to search_form_for!」エラーを解決したい|teratail
「ArgumentError in Posts#index」というエラー文があったのですが、回答者様はここを見て「application.html.erbはどの画面でも共通で呼ばれるため search_form_for が実行されますが、@searchは posts#indexで定義されていないので掲題のエラーにつながっている。」ということを見抜かれました。
詳細はリンクをご覧頂ければと思いますが、回答いただいた「ApplicationControllerとapplication.html.erbではなく、UsersControllerとusers/index.html.erbなど別のコントローラーとビューに処理を持っていく」方法で解決致しました。
今後の予定
今のままだと少しでも名前が分かっていなければ検索が出来ないので、学習時間で検索できるように改良予定です。
参考にしたサイト: Railsでransackを使って検索画面を作る【初心者】 - 平成生まれの資産運用記
Ruby on Railsでransackを用いた検索機能の実装 - Qiita
明日から一番大切なチーム開発2週目が始まります。ここの出来によってほぼ3週目前半でメルカリ開発が終わるチームもあれば、雲行きが怪しく分裂するチームも出てくるとのことなので、コミットできるよう頑張ります。