In Rails 3:
I have the following models:
class System
has_many :input_modes # name of the table with the join in it
has_many :imodes, :through => :input_modes, :source => 'mode', :class_name => "Mode"
has_many :output_modes
has_many :omodes, :through => :output_modes, :source => 'mode', :class_name => 'Mode'
end
class InputMode # OutputMode is identical
belongs_to :mode
belongs_to :system
end
class Mode
... fields, i.e. name ...
end
That works nicely and I can assign lists of Modes to imodes and omodes as intended.
What I'd like to do is use accepts_nested_attributes_for or some other such magic in the System model and build a view with a set of checkboxes.
The set of valid Modes for a given System is defined elsewhere. I'm using checkboxes in the _form view to select which of the valid modes is actually set in imodes and omodes . I don't want to create new Modes from this view, just select from a list of pre-defined Modes.
Below is what I'm currently using in my _form view. It generates a list of checkboxes, one for each allowed Mode for the System being edited. If the checkbox is ticked then that Mode is to be included in the imodes list.
<% @allowed_modes.each do |mode| %>
<li>
<%= check_box_tag :imode_ids, mode.id, @system.imodes.include?(modifier), :name => 'imode_ids[]' %>
<%= mode.name %>
</li>
<% end %>
Which passes this into the controller in params:
{ ..., "imode_ids"=>["2", "14"], ... }
In the controller#create I extract and assign the Modes that had their corresponding checkboxes ticked and add them to imodes with the following code:
@system = System.new(params[:system])
# Note the the empty list that makes sure we clear the
# list if none of the checkboxes are ticked
if params.has_key?(:imode_ids)
imodes = Mode.find(params[:imode_ids])
else
imodes = []
end
@system.imodes = imodes
Once again that all works nicely but I'll have to copy that cludgey code into the other methods in the controller and I'd much prefer to use something more magical if possible. I feel like I've passed off the path of nice clean rails code and into the forest of "hacking around" rails; it works but I don't like it. What should I have done?