Railsで検索機能を実装する

Special Thanks

以下の2つを参考にして実装しました。

github.com

ruby-rails.hatenadiary.com

実装

Railsで、ransackを使ってObjectベースな検索機能を作成していきます。

今作成してるCofwaというコーヒーコミュニティアプリケーションで、豆のブランドの検索をする感じです。なので今回の対象ObjectはBeanというモデルになってます。適宜読み替えてやってくださると助かります。

完成系は以下のような感じ。

movie.gif

1. gemのインストール

まずはgemをインストール。Rails 5の場合は、githubの方からfetchしてこないと動きませんでした。(2016/04/11現在)

# Gemfile
gem 'ransack', github: 'activerecord-hackery/ransack'
$ bundle install

2. 検索機能の作成

以下のように、コントローラに検索するコードを追加します。

class BeansController < ApplicationController
  def index
    @q = Bean.ransack(params[:q])
    @beans = @q.result(distinct: true)
  end
end

3. 検索フォームの作成

ransackのviewのformの使い方は、以下のことを把握しておけばだいたい使うことができると思います。

  • form_for の代わりに search_form_for を使うことで検索フォームを作成する
  • search fieldの名前は、attribute_constとする
  • 関連モデルの場合はsearch fieldの名前は、model_attribute_constとする
  • or, and 検索は attribute_or_attribute_constのようにする。関連モデルも上のルールに従って同様

例えば、viewは以下のようになります。

- # app/views/beans/index.html.haml
%h1 Search Result Beans

= search_form_for @q do |f|
  = f.label :id_cont, "id"
  = f.search_field :id_cont
  %br

  = f.label :origin_name_cont, "オリジン"
  = f.search_field :origin_name_cont
  %br

  = f.label :origin_name_or_bean_variety_name_or_bean_cultivar_name_cont, "オリジン or 種 or 品種"
  = f.search_field :origin_name_or_bean_variety_name_or_bean_cultivar_name_cont
  %br

  = f.submit

%hr

- @beans.each do |bean|
  %h2= bean.id
  %ul
    %li
      id:
      = bean.id
    %li
      origin:
      = bean.origin.name
    %li
      bean variety:
      = bean.bean_variety.name
    %li
      bean cultivar:
      = bean.bean_cultivar.name

完成

これで完成です!めっちゃ簡単YABAI...!!!

movie.gif