Handling a select_tag nil value

A relationship exists between "artist" and "album".

    Artist.rb         has_many :albums

    Album.rb         belongs_to :artist

The edit form for "album" creates/updates this relationship in a database using the "select_tag".

    <%= select_tag('artist_id',         options_for_select([['choose one', '']] +         @artists.collect {|art| [art.name, art.id]},         @album.artist_id)) -%>

resulting in this HTML

    <select id="design_id" name="design_id">         <option value="">choose one</option>         <option value="1">Artist #1</option>         <option value="2">Artist #2</option>         <option value="3">Artist #3</option>

The "album" controller is successfully creating/updating the database **as long as** an option other than "choose one" is selected.

If "choose one" is selected when submitting the form this error is generated:

    ActiveRecord::RecordNotFound in AlbumsController#update         Couldn't find Artist with ID=

    Parameters: {"commit"=>"Edit", "id"=>"1",         "album"=>{"title"=>"Rock", "Rating"=>"1"},         "artist_id"=>""}

Question: How can my controller receive the nil value for "choose one" and successfully process the form?

I think I need a logic statement in my controller, but I am not sure how to acquire and handle the nil value.

AlbumsController currently reads as follows:

  def create     @album = Album.find(params[:id])

    artist = Artist.find(params[:artist_id])     @album.artist = artist

    if @album.update_attributes(params[:album])       flash[:notice] = 'Album was successfully updated.'       redirect_to(:action => 'show', :id => @album)     else       @artists = Artist.find(:all)       render(:action => 'edit')     end   end

Thanks for read this far, I know that is probably too much detail. Your advice is appreciated.

A relationship exists between "artist" and "album".

    Artist.rb         has_many :albums

    Album.rb         belongs_to :artist

The edit form for "album" creates/updates this relationship in a database using the "select_tag".

    <%= select_tag('artist_id',         options_for_select([['choose one', '']] +         @artists.collect {|art| [art.name, art.id]},         @album.artist_id)) -%>

Try this instead:

  select 'album', 'artist_id', @artists.map{|a| [a.name, a.id]},          :prompt => 'Choose one...'

This will pass the artist id (possibly "") as the value of the album[artist_id] parameter, which lets you update it with the call to Album.create or Album update in your controller. That is, there's no need to update this field separately.

AlbumsController currently reads as follows:

  def create     @album = Album.find(params[:id])

    artist = Artist.find(params[:artist_id])     @album.artist = artist

    if @album.update_attributes(params[:album])

So the above 4 lines become something like:

    @album = Album.new(params[:album]) # sets album_id too now     if @album.save

      flash[:notice] = 'Album was successfully updated.'       redirect_to(:action => 'show', :id => @album)     else       @artists = Artist.find(:all)       render(:action => 'edit')     end   end

Thanks for read this far, I know that is probably too much detail.

Not at all; I found your question/problem very clear and easy to follow.

Your advice is appreciated.

You're welcome! George.

Success!

Thank you George.