やはりフォームの作成方法が難しいたぬきです。今回は、collection_check_boxというviewヘルパーの理解にかなり時間がかかったので、備忘も兼ねて整理してみようと思います。
check boxの書き方3つ
そもそも、チェックボックスの書き方なのですが、以下の3つの方法があり、それぞれ以下のように使い分けます。
- check_box_tag(関連するモデルがないとき)
- check_boxメソッド(関連するモデルがあるとき)
- collection_check_boxes(多対多のリレーションのモデルを表現するときに便利)
check_box_tagの書き方
check_box_tagの書き方は以下の通りです。一緒に、ラベルも併記しています。
なお、以下、viewの情報はhamlで書きます。
= check_box_tag :check1
= label_tag :check1, "ラベルのテスト"
実行結果は以下の通り。
一つのチェックボックスができました。
check_box の書き方
check_boxの書き方は以下の通りです。
= check_box :group, :user_ids, {class: "check_box"}, true, false
リファレンスによると、
check_box(オブジェクト名, プロパティ名 [, オプション, checked_value = "1", unchecked_value = "0"])
という構造になっているようで
- 第1引数(オブジェクト名)・・・データを保存したいモデル名
- 第2引数(プロパティ名)・・・データを保存したいカラム名
- 第3引数(オプション)・・・クラス名など。色々入ります。(詳しくはこちら)
- 第4引数、第5引数・・・チェックが入っている時のvalue値を1にするか否か、チェックが入っていない時のvalueを0にするか否かの設定です。
true
やfalse
にもできます。
ちなみに、check_boxではなく、f.check_boxの形にすると(つまり、form_withやform_forの中で使うと、第1引数(オブジェクト)が省略できるようです。
form_withやform_forの中で、関連するモデルは定義していますものね。。。
collection_check_box の書き方
最後に、collection_check_boxを用いたチェックボックスの書き方です。collection
(Railsではインスタンスの集まり)のデータを利用して、(一つ一つ定義しなくても)一気にチェックボックスを作ってしまえる便利メソッドです。
こちらは多対多のリレーション構造の中でチェックボックスを利用するときに便利な書き方、という形で紹介されることが多いのですが、、、
書き方は、こんな感じ
= collection_check_boxes :group, :user_ids, User.all, :id, :name do |user|
= user.label { user.check_box + user.text }
書かれている内容の詳細な解説はこちらのページが詳しいです。
▼collection_check_boxesメソッドの構造確認
https://qiita.com/sho012b/items/3a595fde14516081dff5
▼railsで多対多な関係を実装する時のポイント
https://qiita.com/m-shin/items/0487105994d9281221d4
構造的には、このような形になっていて
collection_check_boxes(object, method, collection, value_method, text_method)
それぞれ、引数は以下のような意味を持ちます。
- 第1引数:データを保存するテーブル
- 第2引数:データを保存するカラム
- 第3引数:ここで指定して持ってきているデータ(配列)の数だけ、チェックボックスが作成される
- 第4引数:生成されるinputタグのvaule属性の値(下記参照)
- 第5引数:生成されるinputタグのテキストとなる値(下記参照)
生成されたHTMLタグはこちら
<input type="checkbox" value="1" name="group[user_ids][]" id="group_user_ids_1">"ここに生成されたテキストが入ります"
check_boxと同様に、form_withなどの中でf.collection_check_boxesのような形で使うときには、第1引数が省略できます!
最後に、こちら2行目の部分ですが、
= collection_check_boxes :group, :user_ids, User.all, :id, :name do |user|
= user.label { user.check_box + user.text }
Apiドキュメントによると、ラベルを生成するためのオプションだそうです。
(上記ドキュメントの下方に「The builder methods label and check_box also accept extra HTML options:」という記述があるので、そちらをみてください)
特に、check_boxの理解とcollection_check_boxの第2引数の理解が甘いですが、2ヶ月ほど前にはお手上げだったカリキュラムも何とか噛み砕いて理解できるようになりました。。。
ちなみに、なぜ多対多の関係で便利かと言うと、:user_ids
の指定で、中間テーブルに必要なデータ(ここでは第4引数で指定しているユーザーの:id
)をドバッと一気に送れるからなのですね〜
formは特別な書き方が多く本当に難しいですね。いつかform周りで得た知識をまとめてみたいです。引き続き精進いたします。
その他
2020年8月、編集リクエストが届いていることに気づき、マージするとともに、当時理解が曖昧だった内容を加筆修正しました。