winfred.nadeau

Great software speaks for itself.

Has_Many Form Helper Select Magic

originally written March 28, 2012
Just wanted to share some magic I found in the Rails docs today. Although it's been a few projects since the last time I needed to create a form with a multiple-select field on it, this time I was determined to find the Rails way to do this common task, none of this monkeying around with controller code. Yes, it's totally magic. Beautiful, time-saving magic. So you have a model that looks like this:

class MyModel < ActiveRecord::Base
  has_many :somethings
  has_many :something_elses, through: :somethings
end
And you want to keep those new/edit forms DRY. All you need to do is take advantage of the ActiveRecord::Assocations#has_many setter, @my_model.something_ids = ["1","2","3"]  
<%= f.select :something_else_ids, SomethingElse.all.collect {|x| [x.name, x.id]}, {}, :multiple => true %>
Specifically, using the :something_else_ids (or :something_ids, or :your_collection_singularized_ids) param name will automagically tell Rails to call @my_model.something_else_ids = params[:my_model][:something_else_ids] to set the categories for that post accordingly, all without modifying the default controller/scaffold #create and #update code. Oh, and it works with has_many :something, through: :something_else, automatically managing the join model (if your join model belongs_to both models as it should). Freaking awesome. This will also automatically have the model's selected categories populate the select field as highlighted when on an edit form. References: From the has_many API docs where I found this. Also the warning from the form helpers guide explains this "type mismatch" when not using the proper form-field/parameter name.