8
2

More than 1 year has passed since last update.

【Rails】enumとransackを使って複数条件での検索を実装する

Last updated at Posted at 2022-02-28

環境

Ruby 3.0.0
Rails 6.1.4.4
ransack 2.5.0
enum_help

何ができるようになるか

スクリーンショット 2022-02-28 9.59.17.png

上記の画像のようにタスクをタスク名とステータスからAND検索できるようになる。
また、ステータスはenumを使って表現できるようになる。

手順

①enumを導入する

ここでは、name(タスク名)を持つTaskモデルにstatus(タスクのステータス)カラムを追加します。
今回は、Taskモデルに未着手着手中完了の3つのステータスを持たせることにします。
その場合、statusにそのまま文字列で保存するやり方もあるのですが、それだと効率が悪いためActiveRecordの機能であるenumを使用して、それぞれのstatusに数値を与えることとします。

not_started_yet: 0,
under_start: 1,
completion: 2

まずはmigrarionファイルの作成です。

% rails g migration AddStatusToTasks status:integer

statusは数値を保存するため、integer型とします。

カラムを追加したら、enumクラスメソッドにカラム名、対応する値を定義します。

app/models/task.rb
class Task < ApplicationRecord
()
  enum status: {
    not_started_yet: 0,
    under_start: 1,
    completion: 2
  }
end

これで、enumの設定は完了です。

②enumの日本語化

次に先ほど定義したシンボルを日本語化します。
日本語化には、enum_helpというgemが便利です。

gem 'enum_help' をGemfileに追加
% bundle install

gemをインストールしたら、locales/ja.ymlに日本語訳を記述していきます。

locales/ja.yml
ja:
  enums:
    task:
      status:
        not_started_yet: "未着手"
        under_start: "着手中"
        completion: "完了"

参考: https://github.com/zmbacker/enum_help

③ransackを使って検索機能の実装

ransackを使うことで検索機能を簡単に実装することができます。

gem 'ransack' をGemfileに追記
% bundle install

先にコントローラの完成形を記します。

app/controllers/tasks_controller.rb
class TasksController < ApplicationController
  before_action :set_q, only: [:index, :search]

  def index
    @statuses = Task.statuses_i18n
  end

  def search
    @tasks = @q.result(distinct: true)
  end

  private

  def set_q
    @q = Task.ransack(params[:q])
  end
end

ここでは、set_qアクションで送られてきたパラメータを元にransackがデータの検索を行います。
そのデータがsearchアクションにてActiveRecord形式に変換され、@tasksに格納されます。

次にviewを記します。

app/views/tasks/index.html.erb
<%= search_form_for @q, url: search_tasks_path do |f| %>

<%= f.label :name_cont %>
<%= f.search_field :name_cont %>

<% @statuses.each do |status| %>
<%= f.check_box :status_eq_any, { multiple: true, include_hidden: false }, status[0] %>
<%= f.label status[1] %>
<% end %>

<%= f.submit %>
<% end %>

ここでのポイントは検索条件の指定方法です。
何やらname_contstatus_eq_anyのようにカラム名に続く文字が存在しています。
これは検索条件を表しており、
contだと〜の文字列を含む
eq_anyだと完全一致した一つ以上のパラメータ
という意味を持ちます。

参考: https://github.com/activerecord-hackery/ransack#search-matchers

まとめ

gemを使うことで、簡単に検索機能を実装することができました。

8
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
2