Rails の collection_check_boxes をカスタマイズする #rails

概要

検索フォームのような、チェックボックスによる複数条件を指定する UI を作ろうとしたときに、 collection_check_boxes を使うとよさそう。

しかし、collection_check_boxes のオプションだけだと input の属性くらいしかいじれないため、 label の class までカスタマイズするのは難しい。

collection_check_boxes にブロックを渡すとブロックの引数で CheckBoxBuilder を受け取れるので、それを使うことで柔軟に変更できる。

やりたいこと

たとえばブートストラップのようなチェックボックスの場合、下記のような HTML にしたい。

<div class="form-check form-check-inline">
  <input class="form-check-input" type="checkbox" id="inlineCheckbox1" value="option1">
  <label class="form-check-label" for="inlineCheckbox1">1</label>
</div>
<div class="form-check form-check-inline">
  <input class="form-check-input" type="checkbox" id="inlineCheckbox2" value="option2">
  <label class="form-check-label" for="inlineCheckbox2">2</label>
</div>
<div class="form-check form-check-inline">
  <input class="form-check-input" type="checkbox" id="inlineCheckbox3" value="option3" disabled>
  <label class="form-check-label" for="inlineCheckbox3">3 (disabled)</label>
</div>

Checks and radios(チェックとラジオ) · Bootstrap v5.0

個々のチェックボックスに、以下のようなカスタマイズが必要になる。

  • input と label それぞれに個別のスタイルを指定したい
  • div で input と label を囲いたい

collection_check_boxes で実現する

ざっくりやることは次の通り。

  • Controller 側で選択肢となるコレクションを作成し、インスタンス変数に格納しておく
  • collection_check_boxes でコレクションを回す
  • ブロック内でカスタマイズする

例えば「著者による投稿検索」をする場合、 authors コレクションを作成し、author_ids を配列パラメータで渡す。

view の実装は↓のようになる。

 <%= form.collection_check_boxes(:author_ids, @authors, :id, :name, { include_hidden: false }) do |builder|
    tag.div class: 'form-check-inline' do
      checked = params[:author_ids]&.include?(builder.value.to_s)
      
      builder.check_box(checked: checked, class: 'form-check-input') + builder.label(class: 'form-check-label')
    end
  end %>

ブロックの引数で CheckBoxBuilder を受け取れるので、柔軟に変更ができる。

上記の例のように、パラメータなんかと value を突き合わせることで選択状態やスタイルを切り替えることもできる。

(include_hidden は必要に応じて)

rails/actionview/lib/action_view/helpers/tags/collection_check_boxes.rb at v7.0.7.2 · rails/rails · GitHub

参考