collection_radio_buttonsでモデルからラジオボタンを一気に生成する、かつenumの値を利用する


 試したこと

タイトルの通りなのですが、こんな構造のenumがありまして、

enum parking: {
    available: 1,
    not_available: 2,
    unknown: 0,
  }

ここから、こんな感じのフォームを生成したいと思っていました。

個人的には、かなりつまづいてしまったので、それまでの過程をメモします。

前提条件

本記事の実装には以下の条件が必要です。

  1. Railsのデフォルトの言語設定が日本語になっている
  2. gem 'enum-help'が入っている

これらについては拙著ですがこちらをご覧ください。

【初心者向け】i18nを利用して、enumのf.selectオプションを日本語化する[Rails]

collection_radio_buttonsを使う

結論から言うと、書いたコードはこちらです。

= f.collection_radio_buttons :parking, Shop.parkings_i18n, :first , :last 

f.collection_radio_buttons のオプションに指定しているのは下記の要素です。

= f.collection_radio_buttons [データを保存するカラム], [コレクション], [ラジオボタンのvalue値] , [ラジオボタンのテキストになる値]

フォームの中で使わずに、collection_radio_buttonsだけで使う場合は、こうなります。以下、APIドキュメントからの引用です。

collection_radio_buttons(オブジェクト名, コレクション名, メソッド名, value値 [, オプション])

どういう仕組みなのか

= f.collection_radio_buttons :parking, Shop.parkings_i18n, :first , :last 

こちらのコードの中身はというとこのようになっています。

p Shop.parkings_i18n
=> {"available"=>"有り", "not_available"=>"無し", "unknown"=>"不明"}

gem 'enum_help'が入っているため、_i18nを末尾につけるだけで、日本語のenumを持ってくることができます。(←ここでかなりはまった)

そして、上記のコードにより、{"available"=>"有り", "not_available"=>"無し", "unknown"=>"不明"}というハッシュが得られるので、

最初の要素をvalue値に、最後の要素をテキストにすればOKです。

classなども付与したいとき

ところで、最終的なコードは、class要素も付与したかったので、以下のようになりました。

= f.collection_radio_buttons :parking, Shop.parkings_i18n, :first , :last do |b|
  = b.label(class: "radio_button") { b.radio_button(class: "radio_button") + b.text }

これで、ラベル付き、クラス付きのラジオボタンが生成されました^^

余談:enumでもう一つはまったところ

ところで、enumでもう一つ動かない!!となっていた点があって…

ja.yml
enums: # 複数形!!
  facility:
    parking:
      available: "有り"
      not_available: "無し"
      unknown: "不明"

上記で、enumsenumになっていたため、なかなかenumの翻訳情報が読み出せずにおりました^^;(enum_helperを介さないところはenumでも動いたので。。。)

複数形にするの、忘れないようにしたいと思います。

参考:チェックボックスの場合

ところで、以前チェックボックスで似たようなものも作ったことがあり、よろしければこちらもご覧ください。

【初心者向け】チェックボックスの書き方あれこれ[Ruby][Rails]

その他の参考記事

こちらの記事には大変お世話になりながら作成しました!
[RAILS]ENUMの値を日本語化してラジオボタンに突っ込む