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 -~----------~----~----~----~------~----~------~--~---