@ledsun blog

Hのキーがhellで、Sのキーがslaveだ、と彼は思った。そしてYのキーがyouだ。

Ruby on Rails のcheck_boxヘルパーはhiddenのinput要素を作る

疑問

check_box | Railsドキュメント によれば

check_box 'page', 'freezeflag', {}, true, false

と書けば、次のようなHTMLを出力します。

<input name="page[freezeflag]" type="hidden" value="false" />
<input id="page_freezeflag" name="page[freezeflag]" type="checkbox" value="true" />

なぜcheckboxのinput要素だけでなく、hiddenのinupt要素も作るのでしょうか?

理由

checkboxが選択されないで送信された時の判定 | ハックノート

checkboxを選択してsubmitするとvalueが送信されます。 しかし、選択していない状態でsubmitするとvalueは{更新されない/nullになります}。

選択していなくてもvalueを送信したい…! そんな時はhiddenを使います。 同じname属性の値はPOST時に上書きされるので、checkboxが選択されていなければ、 以下のコードの場合valueはFがPOSTされます。

以上です。

checkboxのinuput要素のふるまい

checkboxのinuput要素はチェックが入っていない場合は値がPOSTされません。

Railsのcheck_boxのチェック時、アンチェック時にどんな値がサーバに送られるか - mnmandahalfのブログ

f.check_box :remember_me, {} , 1, nil

のように呼び出すと、hiddeのinput要素が出力されません。 このときチェックなしでPOSTするとサーバー側でうけとるのは次の値です。

parameters: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
  email: foo@bar.co.jp
  password: foobar

つまり:remember_meというキーがなくなります。 この情報でモデルを更新しようとすると、わざわざキーを指定する必要があります。 不便です。

hiddenのinput要素で否定の値をセット

そこで前述のようにチェックを外したときに送る値を、hiddenのinput要素で埋め込みます。

<input name="page[freezeflag]" type="hidden" value="false" />

すると、チェックしたときは後ろのcheckboxのinput要素の値で上書きされます。 チェックを外した時は、この値がPOSTされます。