Rubyと筋肉とギターとわたし

エンジニア二年目の雑魚です。プログラミング・ギター・筋トレのことをメインにブログを書いていきます。

【備忘録】Railsでcheck_box_tagがfalseのときもパラメータを飛ばしたい

Rails速習実践ガイドめっちゃいいね、どうもてぃです。

さて、昔実装したのに、しばらくやってないと忘れることよく有りますよね。

今回は備忘録として忘れてたことを書きたいと思います。

環境

やったこと

check_box_tagでパラメータを飛ばす場合、デフォルトではチェックのついたものしか飛びません。ということを完全に忘れていて、軽く30分くらい悩みました。

なので、適切な対処が必要。

まずはcheck_box_tagのリファレンスを確認。おなじみのrailsdocです。

<%= check_box_tag 'page[freezeflag]', true, false, {} %>
# <input id="page_freezeflag" name="page[freezeflag]" type="checkbox" value="true" />

これ使ってみます。

check_box_tagの第一引数はパラメータのkey名 & 属性のIDとname、第二引数は渡す値、第三引数は初期値、第四引数は状態を表してます。

チェックがついていると、strongparameterの中に

{ "page" => <ActionController::Parameters { "freezeflag" => "true" } permitted: false> }

という形で入ります。チェック無しだとそもそも、params["page"]nilになります。

これはデータを更新する上で不便。チェックがあるかどうかで無駄な処理を書かなきゃいけないのはスマートじゃないです。

それを解消するのがhidden_field_tag

必ずcheck_box_tagの前に設置しましょう!

それが以下。

<%= hidden_field_tag 'page[freezeflag]', false %>
<%= check_box_tag 'page[freezeflag]', true, false, {} %>
# <input id="page_freezeflag" name="page[freezeflag]" type="checkbox" value="true" />

check_box_tagにチェックが入らなければ同じ名前のhidden_field_tagの値(false)がパラメータとして飛ぶ。

逆にチェックがついていればcheck_box_tagの方で値が上書きされるという感じ。

必ずnameは同じにしないといけないことに注意。あと最初に言ったけど、hidden_field_tagの位置にも注意。

これで今回の要件を満たせます。

番外編(おまけ)

素晴らしいメソッドを見つけました。

ActiveRecord::Type::Boolean.new.castです。

以下の記事に書いてありました。素晴らしいです。ありがとうございます。

qiita.com

なので、今回飛ばしている値を変更します。

<%= hidden_field_tag 'page[freezeflag]', 0 %>
<%= check_box_tag 'page[freezeflag]', 1, false, {} %>
# <input id="page_freezeflag" name="page[freezeflag]" type="checkbox" value="true" />

これで、パラメータとしてチェック済みの時は文字列の1、チェック無しだと文字列の0が飛びます。

上の記事のように、models/applilcation_record.rbへ専用のメソッドを書いておくと。。。

def checked?(data)
  ActiveRecord::Type::Boolean.new.cast(data)
end

checked?の引数に飛んできたチェックボックスのパラメータを渡すとtrue or falseを判定してくれます。

すばらしい。感動しました。