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) %>
<%= event_type.name %> |
<% 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 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}” }) %>
<%=
event_type.name %> |
<% 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!