Topic: Can't get code right to edit forms

Hi

I am sure I am doing something fundamentally wrong here, but I can't figure out what.  I need to be able to edit some data stored in a table.  If the data fails validation, then I want to be redisplay the form with errors and get the user to try again.  After much battling I have managed to do this, but I seem to be losing the ID on the second iteration of the form.  I think it is something to do with the delete I am doing, but if there is an error, the delete is rolling back (on the database at least - maybe the model has gone?)

I have a table called holidays:

CREATE TABLE `holidays` (
  `id` bigint(20) NOT NULL auto_increment,
  `date_start` date NOT NULL default '0000-00-00',
  `date_end` date NOT NULL default '0000-00-00',
  `holiday_year_id` int(11) NOT NULL default '0',
  `user_id` tinyint(3) unsigned NOT NULL default '0',
  `holiday_type_id` tinyint(3) unsigned NOT NULL default '0',
  `approval_id` tinyint(3) unsigned NOT NULL default '0',
  `approval_reason` varchar(255) NOT NULL default '',
  `updated_on` date NOT NULL default '0000-00-00',
  `created_on` date NOT NULL default '0000-00-00',
  `comment` varchar(255) default NULL,
  `days` float unsigned NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Holds holiday details' AUTO_INCREMENT=62 ;

I have the following code in my holiday_controller.rb:

 def edit
            @holiday = Holiday.find(params[:id])
    end
   
        def update
       @holiday = Holiday.find(@params[:id])
       begin
         Holiday.transaction do
             do_delete(@holiday)
             do_new
        end
           redirect_to(:controller => "user", :action => "show", :id => session[:user_id])
        rescue
           flash[:notice] = "Failed."
           render(:action => "edit")
    end
    end

    def do_delete(holiday)
       holiday.holiday_year.taken -= holiday.days
         holiday.holiday_year.save!
         Holiday.delete(holiday.id)
    end


My edit.rhtml looks like:

    <% @page_title = "Edit Holiday" -%>

<%= error_messages_for("holiday")
%>

<%= start_form_tag :action => 'update', :id => @holiday %>
<p>
<b><label for="holiday_date_start">From:</label></b><br/>
<%= date_select("holiday", "date_start", :order => [:day, :month, :year]) %>
</p>
<p>
<b><label for="holiday_date_end">To:</label></b><br/>
<%= date_select("holiday", "date_end", :order => [:day, :month, :year]) %>
</p>
<p>
<b><label for="type_id">Reason:</label></b>&nbsp;
<%= select("holiday", "holiday_type_id", HolidayType.find_all.collect {|t| [ t.holiday_type, t.id ] }) %>
</p>
<p>
<b><label for="holiday_comment">Comments:</label></b><br/>
<%= text_field "holiday", "comment" %>
</p>
<%= hidden_field("holiday", "approval_id", :value => 1) %>
<%= hidden_field("holiday", "user_id", :value => session[:user_id]) %>

<input type="submit" value="Request"/>
<%= end_form_tag %>
<a href="/user/show">Back</a>


On first entering the edit form the form tag resolves to

<form action="/holiday/update/67" method="post">

I enter invalid data and the form redisplays with the error as it should.  However, the form tag is now

<form action="/holiday/update/" method="post">

The ID is missing, so when you re-submit the correct data, Rails gives an error saying it cannot find a holiday without an ID.

I suspect my delete is doing someting nasty here, but I have rolled back the transaction.  How can I recover the delete model?

I tried the following

        def update
       @holiday = Holiday.find(@params[:id])
       begin
         Holiday.transaction do
             do_delete(@holiday)
             do_new
        end
           redirect_to(:controller => "user", :action => "show", :id => session[:user_id])
        rescue
  >>>         @holiday = Holiday.find(@params[:id])  <<<
           flash[:notice] = "Failed."
           render(:action => "edit")
    end
    end

Which made the form display correctly again, with the ID, but I lost all my error messages.

Can anyone point out where I am going wrong?

Thanks

Mat.

Last edited by matdiss (2006-11-17 12:41:41)

Re: Can't get code right to edit forms

I may be mistaken as I am learning rails myself. but when you render the "edit" action in the delete, you are not passing the id.

what i mean is in the first instance of the edit being called I assume its something like /edit/67 in the url
but when the error occors the url only calls /edit/

sorry if I just wasted your time.

--

Re: Can't get code right to edit forms

Hi

I understand what you mean here and the initial code does call edit with the ID in the URL.

The examples in the rails books do the same as I am doig here however and mine does work if I don't do the delete, so I am assuming that when you call render then the params are the same and it is the same as explicitly stating the ID on the URL.

It seems as though the delete is removing the holiday data from rails 'memory' and not putting it back when the transaction fails and rolls the database back.  Maybe a bug in rails, more likely something I am doing wrong.

Thanks for looking!