I recently figured out a couple tricks for using collection check boxes in a Rails 5 project with Materialize styling.
My goal: Have users check or uncheck programs associated with a classroom. A classroom can have many programs, so I used the Rails collection checkboxes form helper to allow multiple selections.
Implementation: The collection checkboxes form helper generates a labelled checkbox for each item in a collection.
Above, the first argument of collection checkboxes is :program_ids. This represents the method, program_ids, available on each classroom instance. It also will be the name of the key I can access in my params which has the value of all selected program ids.
I passed in @programs as the second argument, which is the collection of programs pulled from my database in my Classrooms controller.
The third argument, :id, refers to the data that will be passed into my params. In this case, I’m going to send the program ids, so that in my Classrooms controller, I can find programs by id in my database.
The final argument, :title, refers to the program’s title, which will be used to label each checkbox so the user will know which program they’re checking or unchecking.
When I added this code to my form, my checkboxes and labels were properly generated, but there was no spacing or formatting. I wanted each program to render on a new line, so I iterated through each program and added divs wrapping the checkbox and label.
When I first implemented the iteration, I had reversed the order of the checkbox and label, and my checkboxes were not appearing. I read a handy Stack Overflow post, which explained that the checkbox must appear before the label when using MaterializeCSS.
Next, I used strong params to access my array of checked programs, and update the classroom’s programs in my Classrooms controller’s update method. While I ultimately ended up refactoring my controller, this was my initial approach:
I used the delete_if method on line five, because the array of ids in my params included empty strings for unchecked boxes.
Refactor: I suspected that there was a more efficient way to update the classroom’s programs from my array of program ids in the Classrooms controller, since my original version involved two iterations and several database calls.
It turns out that I had made the job of updating my associations much more difficult for myself than necessary. In fact, I can simply pass the classroom’s update method my array of program ids, and it’ll take care of the rest: