Associated models HABTM form problems

I’m building an app for displaying events information.

The app has a database of bands, and events

an event can have many bands, and a band can have many events, so I’ve
gone for a has_and_belongs_to_many association between the two models,
with the join table bands_events.

In order to be able to dynamically add bands, I’ve refactored the ‘add a
band’ part of the form into a partial called _band, this form has 2
parts, a text_field to enter the name of a new band, or a
collection_select drop down select box to select a band already stored.
The idea is that you can make a new band on the fly by typing into the
text_field, or you select an existing one from the menu.

The text field is working fine, and creates new associated bands, but
the collection_select selection isn’t getting passed through correctly,
and I’m very confused…

(I got the code from R Bates’s railscast on complex forms pt 2)

my controller initialises the band into memory
EventsController
def new
@event = Event.new
@bands = Band.order(’“band_name” ASC ')
1.times {@event.bands.build}
end

The views are currently very simple ( in haml if you’re thinking it
looks weird!)

---------------------------- new.html.haml
%h1 Create a new event

=form_for [:events_admin, @event], :url => events_admin_events_path,
:html => { :multipart => true } do |f|
=render :partial=>“events_form”, :locals=>{:event => @event, :f=>f}

---------------- _events_form.html.haml

%fieldset
.half
=f.label “Event Name”
=f.text_field :event_name

=render :partial => "band", :collection => @event.bands

=f.submit "Save Event"

----------------- _band.html.haml

=fields_for “event[band_attributes][]”, band do |band_form|
=band_form.label “Add a new band”
=band_form.text_field :new_band_name

// This is not working at all, for some reason the params are not
being passed through
=band_form.label “Select from saved Bands”
=collection_select(band, :saved_band_name, @bands, :band_name,
:band_name, {:selected => @selected_band})

when the submit button is pressed, the method band_attributes= is called
in the Event model class, and that looks like this:

event.rb - class Event < ActiveRecord::Base

def band_attributes=(band_attributes)

band_attributes.each do |attributes|
  new_band_name = attributes[:new_band_name]

  logger.debug"______NEW BAND NAME FROM PARAMS _______"
  logger.debug(new_band_name)

  if new_band_name.empty?
    saved_band_name = attributes[:saved_band_name]
    band_object = Band.where(:band_name => saved_band_name)[0]
    logger.debug"______ BAND NAME FROM PARAMS DROP DOWN LIST

_______"
logger.debug(saved_band_name)

  else
    attributes[:band_name] = new_band_name
    bands.build(attributes)
  end


end

end # of band_attributes

Typing into the text_field works fine, the new_band_name gets passed
through, and saved, but the saved_band_name from the collection select
drop down list does not get passed through in the band_attributes.

From looking at the logs, it looks like the ‘saved_band_name’ parameter
is not getting grouped with the other band data

LOGS:

Parameters: {“commit”=>“Save Event”,
“authenticity_token”=>“bRJcMHn+PL3pwpeVcgyUpd/IgRjNiGih2cfadZoPJSk=”,
“utf8”=>“✓”, “#Band:0x1049e4008”=>{“saved_band_name”=>“A BAND I’VE
SAVED”}, “event”=>{“band_attributes”=>[{“new_band_name”=>""}],
“start_time(1i)”=>“2011”, “music_sample_link”=>""………

Does anyone know what is going on here, and how I can get the parameter
from the collection_select box to be passed in the same hash as the
new_band_name??

All help appreciated massively.

Mike

On Feb 27, 5:12pm, Michael B. [email protected] wrote:

The text field is working fine, and creates new associated bands, but
the collection_select selection isn’t getting passed through correctly,
and I’m very confused…

(I got the code from R Bates’s railscast on complex forms pt 2)

Not answering your question directly, but these days you probably want
to use the accepts_nested_attributes stuff that is built into rails
2.3 and higher.

=band_form.label “Select from saved Bands”
=collection_select(band, :saved_band_name, @bands, :band_name,
:band_name, {:selected => @selected_band})

That first argument to collection_select should be the name of the
attribute, ie a symbol or string rather than an actual instance of
band. The easy way would be to use the form builder, ie
band_form.collection_form :saved_band_name, … just like you’re doing
with other form inputs

Fred

Thanks for your help!

=band_form.label “Select from saved Bands”
=collection_select(band, :saved_band_name, @bands, :band_name,
:band_name, {:selected => @selected_band})

That first argument to collection_select should be the name of the
attribute, ie a symbol or string rather than an actual instance of
band. The easy way would be to use the form builder, ie
band_form.collection_form :saved_band_name, … just like you’re doing
with other form inputs.


I really didn’t know I could use collection select in this way, thanks
for the tip, not quite sure how it’s working, but

band_form.collection_select :saved_band_name, @bands, :band_name,
:band_name, {:selected => @selected_band}

seems to be passing the selected band name through exactly as it should
be :-))

On Feb 28, 3:27pm, Michael B. [email protected] wrote:

with other form inputs.


I really didn’t know I could use collection select in this way, thanks
for the tip, not quite sure how it’s working, but

band_form.collection_select :saved_band_name, @bands, :band_name,
:band_name, {:selected => @selected_band}

It’s exactly the same as band_form.text_field. The form builder object
(ie band_form) encapsulates the object being edited & info about the
appropriate prefix for the input names.

Fred

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs