どこまでを前提として文章を書くか。それを考えることが難しい。
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 }
こうしてかけた。
おわり
すごく久しぶりに技術記事を書いた気がする。これからは投稿の頻度を増やそう。