Saturday, August 22, 2015

Checklists In Rails 4

This will briefly cover how to create a many-to-many form checklist using the Rails 4 method collection_check_boxes.

In this scenario we'll have a User model (with a first_name and last_name) and a Subject model (with a name). A User should be able to select multiple Subjects. The User/Subject associations are both many-to-many.

If you don't already have it, add the associations to your models and create a linking table.

app/models/subject.rb
has_and_belongs_to_many :users
app/models/user.rb
has_and_belongs_to_many :subjects
db/migrate/[DATETIME]_create_join_table_user_subject.rb
class CreateJoinTableUserSubject < ActiveRecord::Migration
  def change
    create_join_table :users, :subjects do |t|
      t.index [:user_id, :subject_id]
      t.index [:subject_id, :user_id]
    end
  end
end
Next, allow your UserController to accept an array of Subject IDs in its parameters.

app/controllers/users_controller.rb
private
  def user_params
    params.require(:user).permit(:first_name,
                                                   :last_name,
                                                   :subject_ids => [])
  end
To generate the checklist collection_check_boxes will, by default, render all of your checkboxes with labels next to each other. I want them stacked so I've added a block to the end. Inside of the block, you can define the HTML generated for each item using the check_box and label helper methods.

app/views/users/edit.html.erb
<%= form_for(@user) do |f| %>
  <p>Subjects</p>
  <%= f.collection_check_boxes(:subject_ids, Subject.all, :id, :name) do |s| %>
    <%= s.check_box %> <%= s.label %> <br />
  <% end %>
  <%= f.submit "Update Your Subjects" %>
<% end %>
Assuming you have an update route already functioning in your UserController, your @user.update(user_params) should be good to go. If you'd like to display a User's selected Subjects, you can use @user.subjects.map{|s| s.name}.join(', ').

Relevant Links

No comments:

Post a Comment