Mark Reginald James wrote:
> Michael Kahle wrote:
> 
> 
>> Super!  Thanks so much.  It worked perfectly.  The only thing I changed 
>> from your example was to handle the update as a transaction.  Updating 
>> @registration and @customer with the ".attributes" method did the trick 
>> perfectly.  I am off to experiment with the "validates_associated 
>> :customer".
> 
> Could you explain a little more what you changed and why.

I will do my best; it certainly helps to re-enforce what I've learned.

In your example you provided, what was to me, a novel idea in terms of 
updating the @snowplow_registration and @customer objects.  When these 
objects were first created in the update method, they had the properties 
of a newly fetched record from the database.  It wasn't until I called 
on each of these:
      @snowplow_registration.update_attributes!(params[:snowplow_registration])
      @customer.update_attributes!(params[:customer])
respectively, did the newly created objects, instantiated at the 
beginning, take on the properties of my submitted form.  My problem was 
that when the transaction failed during the first update, I would never 
see the newly created @customer object updated with my form information. 
By calling the ".attributes = params[]" method on each of these BEFORE I 
started my transaction I now had in memory the new form data I entered 
to pass to my rescue catch.  In your code, you check the Customer object 
before submitting it to be written.

I was about to write about how important it was for me to do this update 
in a transaction because of the possibility of the database failing in 
between writes and how your code didn't account for that.  I glanced 
over your code when I saw:
      if @snowplow_registration.valid? && customer_valid
and simply assumed you were doing a standard non-transactional save to 
the database.  Now that I'm inspecting this more closely, I see that you 
did-in-fact keep this a transactional operation.  Here is the code I am 
using now:

  def update
    @snowplow_registration = SnowplowRegistration.find(params[:id])
    @customer = @snowplow_registration.customer

    @snowplow_registration.attributes = params[:snowplow_registration]
    @customer.attributes = params[:customer]


    SnowplowRegistration.transaction do
      @snowplow_registration.update_attributes!(params[:snowplow_registration])
      @customer.update_attributes!(params[:customer])
      flash[:notice] = 'Snow Plow Registration was successfully 
updated.'
      redirect_to(@snowplow_registration)
    end

  rescue ActiveRecord::RecordInvalid => e
    @customer.valid?
    render :action => "edit"
  end

As you can see the only changes I've made from my first post are:

1) I originally had in my 3rd line:
      @customer = Customer.find(@snowplow_registration.customer)
   and changed it to what you had:
      @customer = @snowplow_registration.customer
   I thought your way looked cleaner.

2) I then added:
      @snowplow_registration.attributes = params[:snowplow_registration]
      @customer.attributes = params[:customer]
   as I explained above, this did the trick to update BEFORE
   my transaction occurred, the @customer and @registration classes.

I had to change nothing else from my original example as the checks are 
already in place.

> One little improvement: Use save_without_validation! to prevent
> the validations from being run twice.

Another good thought, however what I am using now doesn't have the same 
duplication as your suggested code does.  Unless of course when I call 
the "attributes" method it runs a check then as well.  I'm not sure that 
is the case.  I'll have to think about that.

Thank you so much for this discussion and all the wonderful new tidbits 
you've showed me.  Like I said above, this discussion just helps 
reinforce the things that I am learning.
-- 
Posted via http://www.ruby-forum.com/.

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Talk" group.
To post to this group, send email to rubyonrails-talk@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to