やりたいこと
railsでタスク管理アプリを作成。
enumで定義したタスクの状態を検索フォームにcheck_boxとして作成し、
絞り込み検索を行いたい。
※以下のようなイメージ
実装したこと
- controller
class TasksController < ApplicationController
def index
@tasks = current_user.tasks.
status(params[:status])
@status = params[:status]
end
end
実際には他にも絞り込みたい条件はあると思いますが、
今回はstatusのみに絞ってます。
- view
<div class="form-group col-5">
<%= f.label :status, Task.human_attribute_name(:status) %>
<div class="radio">
<%= f.collection_check_boxes :status, Task.statuses, :first, :first do |s| %>
<%= s.check_box checked: @status.nil? || @status.include?(s.value) %>
<%= s.label { Task.human_attribute_name("status.#{s.text}")} %>
<% end %>
</div>
</div>
enumを利用したイメージ画像のようなcheck_boxはこれで作れると思います。
- model
class Task < ApplicationRecord
enum status: { waiting: 0, working: 1, completed: 2 }
scope :status, ->(s) { where(status: Task.statuses.keys & s) if s.present? }
end
modelにscopeを定義しました。
scopeについてはRailsガイドをご参照ください。
スコープの中身について説明します。
- scopeで
->(s)
のように書けばcheck_boxで選択されたパラメータを引数として渡すことができます。 -
Task.statuses.keys
はenum
のkey部分の配列です。
irb(main):001:0> Task.statuses
=> {"waiting"=>0, "working"=>1, "completed"=>2}
irb(main):002:0> Task.statuses.keys
=> ["waiting", "working", "completed"]
-
Array#&
は集合の積演算です。
check_boxで着手中(working)
と完了(completed)
で検索した場合、
以下のような処理になるイメージです。
## Task.statuses.keys & ["working", "completed"]
irb(main):001:0> ["waiting", "working", "completed"] & ["working", "completed"]
=> ["working", "completed"]
これでTaskモデルに対して
SELECT "tasks".* FROM "tasks" WHERE "tasks"."user_id" = 1 AND "tasks"."status" IN (1, 2)
のようなクエリを渡すことができました。
以上、enumを利用したcheck_boxを作成し絞り込み検索を行う実装でした。
少しでも参考になれば嬉しいです。