Posted over 5 years ago. Visible to the public. Repeats. Linked content.

Rails 4 introduced collection_check_boxes

Starting from Rails 4.0, you can use a special form options helper called #collection_check_boxes. It behaves similar to #collection_select, but instead of a single select field it renders a checkbox and a label for each item in the collection.

= form_for @post do |form| = form.collection_check_boxes :author_ids, Author.all, :id, :name_with_initial

How generated form params look like

If you have authors with the IDs 1, 2 and 3, the check boxes above will be named like this:

<input type="checkbox" name="post[author_ids][]" value="1"> <input type="checkbox" name="post[author_ids][]" value="2"> <input type="checkbox" name="post[author_ids][]" value="3"> <input type="hidden" name="post[author_ids][]" value="">

Note the hidden input at the end. This is a trick that Rails uses so users can uncheck all the check boxes. If this hidden input wasn't there, the form param author_ids[] would be missing from the params entirely, and the list would not be set on your model.

In your Rails controller, this will create params like this:

{ 'post' => { 'author_ids' => ['1', '2', '3', ''] } }

Permitting array params in your controller

Note that you need some special syntax to whitelist an array-valued parameter in your controller.

This will not work:

params[:post].permit(:subject, :body, :author_ids)

In your server log you will see a line:

Unpermitted parameters: author_ids

You need to say this instead:

params[:post].permit(:subject, :body, :author_ids => [])

Also, you might need to remove the blank when processing the parameter. You can do so like this:

p = params... p[:author_ids].reject!(&:blank?) # Remove Rails' blank collection item

Customizing the output

You can customize the output by passing a block. The block will be called with a special builder object that has a handful of special methods. See the complex example below.

form.collection_check_boxes :author_ids, Author.all, :id, :name_with_initial do |b| b.label { b.check_box } # or b.label(class: "my-#{ }", 'data-value': b.value) { b.check_box + b.text } end

The return values of each call will be joined and returned. You may of course render HTML inside the block:

# _fields.html.haml = form.collection_check_boxes :author_ids, Author.all, :id, :name_with_initial do |b| .my-checkbox-wrapper = b.label do = b.text = b.check_box

Radio buttons

There is also #collection_radio_buttons.

Once an application no longer requires constant development, it needs periodic maintenance for stable and secure operation. makandra offers monthly maintenance contracts that let you focus on your business while we make sure the lights stay on.

Owner of this card:

Dominik Schöler
Last edit:
over 1 year ago
by Dominik Schöler
strong, params, strong, parameters
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code
Posted by Dominik Schöler to makandra dev
This website uses short-lived cookies to improve usability.
Accept or learn more