マトリョーシカ的日常

ワクワクばらまく明日のブログ。

Railsのcollection_check_boxes を部分的に出力させる

どこまでを前提として文章を書くか。それを考えることが難しい。

Railsには入力フォームを生成するためのフォームヘルパーというものが備わっている。今回は、チェックボックス群を生成するcollection_check_boxes を利用した。ちょっとやりかたに詰まってしまったので、ここに書き残しておく。

メソッドの紹介

任意のオブジェクトに関連づけられたコレクションをフォームにしたいことがある。例えば、都道府県の住所一覧や、ユーザーのスキルリストなど。フォームの種類はいくつかあるが、わたしはその中からチェックボックスを利用する。

以下のメソッドを使う。

ActionView::Helpers::FormBuilder

collection_check_boxes(method, collection, value_method, text_method, options = {}, html_options = {}, &block)

このメソッドはActionView::Helpers::FormOptionsHelper#collection_check_boxesというメソッドをラップ、つまりは内包しているとのこと。引数の意味を確認する。

method

 チェックボックスに表示させる値として、オブジェクトのインスタンスメソッドまたは属性を指定する。

collection

 これはそのままコレクション。表示させるオブジェクトの集合を表す。

value_method

 HTMLに出力した時のvalue属性を指定する。

text_method

 HTMLに出力した時の表示値を指定する。

具体例

 リファレンスにあったコードを書き出す。

<%= form_for @post do |f| %>
  <%= f.collection_check_boxes :author_ids, Author.all, :id, :name_with_initial %>
  <%= f.submit %>
<% end %>

ひとつの投稿について、筆者を選ぶフォームである。第二引数のcollectionはAuthor.all なので、著者データの全てがチェックボックスの選択範囲になる。第一引数の:author_idsによって、@post.author_ids が指定される。これによって@postに関連づけられた著者データが出力される。第二引数の中に、あてはまるデータがあればそれが初期値としてチェックされる。

第四引数はオブジェクトモデルで定義されているメソッドであり、この場合は以下の例にメソッドの記述がある。

ActionView::Helpers::FormOptionsHelper

やりたいこと

 ここからやっと本題。ユーザーに関連づけられたデータをチェックボックスで表示させたいが、そのデータを一度に全て表示するのではなくカテゴリーごとに表示させたい。データの関連をまとめる。

 ユーザーは学習コースのうち、いづれかを選択している。コースは複数のカテゴリを持つ。カテゴリは複数のプラクティスを持つ。

 ユーザーが選択しているコースのカテゴリをeachメソッドでひとつずつ出力させ、そのカテゴリに属するプラクティスをコレクションに含める。今回はerbではなくslim形式で書いた。cssクラスなど不要なところは省略してる。

= form_with model: user, url: url  do |f|
 - user_categories = user.course.categories
 - user_categories.each do |category|
  = f.collection_check_boxes :practice_ids, category.practices, :id, :title, class: 'label-checkbox' do |b|
   = b.check_box(class: 'a-toggle-checkbox')
   = b.label { b.text }

 こうしてかけた。

おわり

 すごく久しぶりに技術記事を書いた気がする。これからは投稿の頻度を増やそう。

Unsplash eberhard 🖐 grossgasteiger