Handling two models in one form

I am just beginning with RoR and ran into my first major headscratcher.

I have a model "events" which is through "has_and_belongs_to_many" (habtm) connected to a model "event_types", meaning one event can have several event_types and one event_type can belong to several events. First question: is there a better way to solve this relationship?

Alright, now when creating a new event I want to show the list of existing event types and let the user choose one or more for the new event through checkboxes.

I fiddled around with how to show the text boxes. I am using "form_for :event" so I tried to use "form.check_box" but I couldn't get it right.

I got it (halfway) working with the following but it is not pretty:

<% @event_types.each do |event_type| %>   <%= check_box_tag "selected_event_types", event_type.id, @event.has_event_type_by_id?(event_type.id) %>   <label for="selected_event_types"><%= event_type.name %></label> | <% end %>

And in the events_controller:

def new   @event = Event.new   @event_types = get_all_event_types   @locations = get_all_locations end

def create   @event = Event.new(params[:event])   params[:selected_event_types].each do |event_type_id|     @event.add_event_type_by_id(event_type_id)   end   if @event.save     redirect_to_index("Event was successfully created.")   else     @event_types = get_all_event_types     @locations = get_all_locations     render :action => :new   end end

It does work, I get a list of the selected event type ids in params[:selected_event_types] but I am sure there must be a smarter way to do this... Moreover, every checkbox gets the same id ("selected_event_types"), so my <label> doesn't work properly...

I am open for all thoughts and ideas!

/Zoop

Ok, I came a bit further in my quest for the perfect solution...

In the view I replaced my old code by this:

<% @event_types.each do |event_type| %>   <%= check_box_tag("event[event_types]",     event_type.id,     @event.has_event_type_by_id?(event_type.id),     { :id => "event_event_types_#{event_type.id}" }) %>   <label for="event_event_types_<%= event_type.id %>"><%= event_type.name %></label> | <% end %>

Now I get the event_types in a subarray of params[:event] into my controller.

In the controller I want to be able to save the event directly without having to add the selected event types "by hand". So my create function looks like this now:

def create   @event = Event.new(params[:event])   if @event.save     redirect_to_index("Event was successfully created.")   else     @event_types = get_all_event_types     @locations = get_all_locations     render :action => :new   end end

Thus I simply removed the lines params[:selected_event_types].each do |event_type_id|   @event.add_event_type_by_id(event_type_id) end

The error I get now is "EventType expected, got String" which is understandable since the value of the checkboxes is "event_type.id". Setting the value to "event_type" doesn't work since i then get "event_type.to_s", the string representation.

What to do?

I found the solution here -> http://wiki.rubyonrails.org/rails/pages/HowtoUseFormOptionHelpers Look under "Assigning to has_many or has_and_belongs_to_many collections"

Changed my code to

[...] <%= check_box_tag("event[event_type_ids]", [...]

and now it works fine!