gemのransackを使って、検索機能の簡単実装
#前提条件
Ruby 2.3.0
Ruby on Rails 5.1.1
参考にしたサイト
https://qiita.com/LuckOfWise/items/e020e896e71d47d0c6a4
まずはransackのgemをインストール
Gemfileに以下を追加。
gem 'ransack'
で
bundle install
これでransackのgemが使えるようになりました。
まずコントローラのインスタンス変数に検索したいオブジェクトをransackメソッドを使い代入し、
それをresultメソッドで受け取ったものをインスタンス変数に代入する。
app/controllers/blogs_controller
def index
@keyword = Blog.ransack(params[:q]) #:q(query)は検索窓に入力された値をパラメータで取得
@blogs = @keyword.result
end
お次は、viewで検索窓を作成する。一般的だとfor_tag使用して書くらしいが、
ransackでは、すでに用意されたsearc_form_forというビルドツールが使えます。
views/blogs/index.html.erb*
<%= search_form_for(@keyword, method: :get) do } |f| %>
<%= f.label :title_cont_any %><br>
<%= f.submit '検索する' %>
<% end %>
カラムの後の_cont_any
の説明はここへ
https://qiita.com/nysalor/items/9a95d91f2b97a08b96b0
検索をかけるワードへの条件のようです。これransackの最低限のことはできます。
複数ワードのAND検索
上記のままだと検索窓に"代々木 カフェ","築地 海鮮丼"のようなスペースを使用したand検索ができません。
原因はparameterで受け取った値が{"title_cont_any"=>["代々木 カフェ"]}
のままでしたので、2つの単語に別けた配列にしたいです。理想→["代々木","カフェ"]
app/controllers/blogs_controller
def index
if params[:q] != nil
params[:q]['title_cont_any'] = params[:q]['title_cont_any'].split(/[\p{blank}\s]+/)
@keyword = Blog.ransack(params[:q])
@blogs = @keyword.result
else
@keyword = Blog.ransack(params[:q])
@blogs = @keyword.result #検索の結果を受け取る。
end
end
何も検索をかけてない状態(初期状態)ですと、paramsにnilが返ってきていたので、splitメソッドがnilclassのエラーを起こしていたので、条件分岐しました。
参考:https://qiita.com/EastResident/items/54047e6e85dda0418dad