rbc_helpers - attr_enumerable

現在一人で作っているアプリがありまして、それで使う機能をRailsプラグインとしてrbc_helpersを作っています。ドキュメントはちゃんとまとめようと思ってますが、ひとまずブログに書いてみようかなーって思ってます。

attr_enumerable

モデルに一つあるいは複数選択可能な選択肢を記述して、属性と関連付け、簡単にビューにradioやcheckboxのタグとして出力できるようにするための機能を提供します。

その実現のために、モデルにenum, enum_arrayというメソッド、ヘルパーメソッドとしてradio_button_group, check_box_groupというメソッドを追加します。

これは以前、columariという名前で作ったプラグインの機能を再度作り直したものです。

enum と radio_button_group

モデル上で以下のように宣言すると、

  class Person
    enum :gender_cd do
      entry 'M', :male, "男性"
      entry 'F', :female, "女性"
      entry 'O', :other, "その他"
    end
  end

Person#gender_keyで:male/:female/:otherのいづれかが取得・設定できますし、Person#gender_nameで"男性"/"女性"/"その他"が取得できます。

で、ビューでradioとして出力するためには、

  <%= f.radio_button_group 'gender_cd' %>

あるいは

  <%= radio_button_group 'person', 'gender_cd' %>

とすると、HTMLとして

<input id="person_gender_cd_m" type="radio" value="M" name="person[gender_cd]" checked="checked"/>
<label for="person_gender_cd_m">男性</label>
<input id="person_gender_cd_f" type="radio" value="F" name="person[gender_cd]"/>
<label for="person_gender_cd_f">女性</label>
<input id="person_gender_cd_o" type="radio" value="O" name="person[gender_cd]"/>
<label for="person_gender_cd_o">その他</label>

が出力されます。

enum_array と check_box_group

enumでは選択肢の中から一つしか選べませんが、複数選択可能にしたい場合はenum_arrayが使えます。

    enum_array :strike_zone do
      entry 10, :under_teens, "〜10代"
      entry 20, :twenties, "20代"
      entry 30, :thirties, "30代"
      entry 40, :fourties, "40代"
      entry 50, :fifties, "50代"
      entry 60, :sixties, "60代"
      entry 70, :seventies, "70代"
      entry 80, :eighties, "80代〜"
    end

とすると、strike_zone_idsで各entryのid(10,20,・・・)の配列の取得/設定、strike_zone_idsで各entryのkey(:under_teens, :twnties, ・・・)の配列の取得/設定、strike_zone_namesで各entryのname("〜10代", "20代", ・・・)の配列の取得ができます。
で、ビューで

<%= f.check_box_group 'strike_zone' %>

とすると、

<input id="person_strike_zone_10" class="person_strike_zone_check_boxes" type="checkbox" value="10" checked="checked"/>
<label for="person_strike_zone_10">〜10代</label>
<input id="person_strike_zone_20" class="person_strike_zone_check_boxes" type="checkbox" value="20" checked="checked"/>
<label for="person_strike_zone_20">20代</label>
<input id="person_strike_zone_30" class="person_strike_zone_check_boxes" type="checkbox" value="30" checked="checked"/>
<label for="person_strike_zone_30">30代</label>
<input id="person_strike_zone_40" class="person_strike_zone_check_boxes" type="checkbox" value="40"/>
<label for="person_strike_zone_40">40代</label>
<input id="person_strike_zone_50" class="person_strike_zone_check_boxes" type="checkbox" value="50" checked="checked"/>
<label for="person_strike_zone_50">50代</label>
<input id="person_strike_zone_60" class="person_strike_zone_check_boxes" type="checkbox" value="60"/>
<label for="person_strike_zone_60">60代</label>
<input id="person_strike_zone_70" class="person_strike_zone_check_boxes" type="checkbox" value="70"/>
<label for="person_strike_zone_70">70代</label>
<input id="person_strike_zone_80" class="person_strike_zone_check_boxes" type="checkbox" value="80"/>
<label for="person_strike_zone_80">80代〜</label>
<input id="person_strike_zone" type="hidden" value="10,20,30,50" name="person[strike_zone_ids]"/>
<script>
1new HTMLInputElement.CheckboxText($("person_strike_zone"), "person_strike_zone_check_boxes", {"separator": ",", "observeCheckboxes": false, "object": null, "applyAutomatically": true});
</script>

というHTMLが出力されます。これで複数のcheckboxの出力を簡単に書くことができます。

radio_button_groupもcheck_box_groupも書くradioやcheckboxなどをspanで囲みたい場合などにも対応可能ですが、その説明は後日・・・。とりあえずサンプルアプリを見ていただければ分かると思います。