~/ Customize Rails Collection Checkboxes

If you are using Rails' form helper collection_check_boxes, it's not entirely obvious how you might go about customizing the label's html.

The "Normal Way" #

...or what frequently shows up in the documentation.

Say we have the following Ruby classes:

class Post < ActiveRecord::Base
has_and_belongs_to_many :authors
class Author < ActiveRecord::Base
has_and_belongs_to_many :posts
def name_with_initial
"#{first_name.first}. #{last_name}"

The easiest way to create a group of checkboxes is with collection_check_boxes:

<!-- app/views/carts/new.html.erb -->
<%= collection_check_boxes(:post, :author_ids, Author.all, :id, :name_with_initial) %>

This generates the following HTML:

<input id="post_author_ids_1" name="post[author_ids][]" type="checkbox" value="1" checked="checked" />
<label for="post_author_ids_1">D. Heinemeier Hansson</label>
<input id="post_author_ids_2" name="post[author_ids][]" type="checkbox" value="2" />
<label for="post_author_ids_2">D. Thomas</label>
<input id="post_author_ids_3" name="post[author_ids][]" type="checkbox" value="3" />
<label for="post_author_ids_3">M. Clark</label>
<input name="post[author_ids][]" type="hidden" value="" />

The Not-so-normal Way #

If you don't have access to the Author class, as was my case when working with the Stripe API, you have two options.

Add to the open ruby class #

Opening a class definition on the class for which you don't have access allows you to define new methods on a class:

class Author
def name_with_initial
# code accessing instance


Pass a block to the form helper #

collection_check_boxes(:post, :author_ids, Author.all, :id, :name_with_initial) do |b|
b.label do
b.object.first_name.first + ". " + b.object.last_name

Boom! The instance for each of the radio buttons is available on the object method as seen above.

~/ Posted by Jesse Shawl on 2017-01-25