Edited at

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の使い方を思い出す所からになりますね...