Ruby
Rails

Rails4で複数のチェックボックスを扱う

More than 3 years have passed since last update.

ゴール

kobito.1431474217.459692.png

こういうフォームを作って

{"colors"=>["オレンジ", "イエロー"]}

という風に受け取ることが出来る。

html側

今回は特にモデルを作成するわけではなく、画面でコレクションを生成して投げる形にします。(趣味でhamlで書いてます)

edit.haml
= form_tag '/sample/confirm', method: :post do
  - %w(レッド オレンジ イエロー).each do |item|
    %label
      = check_box_tag 'sample_form[colors][]', item
      = item
  = submit_tag('送信')

controller側

strong parametersを設定する

sample_controller.rb
private

def post_params
  params.require(:sample_form).permit(
    colors: []
  )
end

配列を受けたい場合はこう。

p post_paramsをすると、colorsに配列が格納されているはず。

collection_check_boxesを使ってみる

izumin5210さんに, collection_check_boxesというview helperがあることを教えて頂いたので、それでも実装してみます。
※ドキュメント的にはどうみてもActiveRecord前提なのですが、DB関係ない画面を想定しているので、ActiveModelを使います。

collection_check_boxes(method, collection, value_method, text_method, options = {}, html_options = {}, &block)
...

なので、collectionとその要素のvalueとtextに対するアクセサがあれば動きそう。

controller側

サクッとcontroller側でオブジェクトを作ります

sample_controller.rb
class SampleController < ActionController::Base
  class Post
    include ActiveModel::Model

    attr_accessor :colors
  end

  class Color
    include ActiveModel::Model

    attr_accessor :name
  end

  def index
    colors = [Color.new(name: 'イエロー'), Color.new(name: 'オレンジ'), Color.new(name: 'ピンク')]
    @form = Post.new(colors: colors)
  end

  def confirm
    p post_parms
  end

  private

  def post_parms
    params.require(:sample_controller_post).permit(colors: [])
  end
end

html側

sample.haml
= form_for @form, url: {action: 'confirm'} do |f|
  = f.collection_check_boxes(:colors, @form.colors, :name, :name)
  = f.submit('送信')

valueと表示させる内容が一緒なので、nameを渡している。

画面でイエローとピンクを選択して、postし、pした結果はこんな感じ。

result
{"colors"=>["イエロー", "ピンク", ""]}

まとめ

collection_check_boxesのドキュメントを見ると

document
collection_check_boxes(:post, :author_ids, Author.all, :id, :name_with_initial)

こういう感じでActiveRecordなオブジェクトを前提にしているのですが、素で書くよりかは短くなりました。
バリデーションかけてリダイレクトして再表示〜とかやろうとすると、paramsからの再構成を考えないといけないですね。それはまたの機会とさせてください。

雑談

Railsでたまに画面を作ると、view helperの使い方を思い出す所からになりますね...