multiple object validation inconsistency

Hello,

I am updating two objects from a form with the code:

def update     @court = Court.find(params[:id])     @address = @court.address

    valid = @court.valid?

    if @address.valid? and valid and @court.update_attributes(params[:court]) and       @address.update_attributes(params[:address])       flash[:notice] = 'Court was successfully updated.'       redirect_to :action => 'show', :id => @court     else       render :action => 'edit'     end   end

If the address fails validation I get an error message like I would expect and the information that the user just keyed is redisplayed to the user.

If the court and address both fail validation, the error messages appear, but the address data reverts to the state in the database and the user changes are lost. I assume it is the way I am loading the address, which doesn't look correct to me, but it does work when the court information passes validation.

Any help would be appreciated.

Thanks, Dan

Dan Munk wrote:

Hello,

I am updating two objects from a form with the code:

def update     @court = Court.find(params[:id])     @address = @court.address

    valid = @court.valid?

    if @address.valid? and valid and @court.update_attributes(params[:court]) and       @address.update_attributes(params[:address])       flash[:notice] = 'Court was successfully updated.'       redirect_to :action => 'show', :id => @court     else       render :action => 'edit'     end   end

If the address fails validation I get an error message like I would expect and the information that the user just keyed is redisplayed to the user.

If the court and address both fail validation, the error messages appear, but the address data reverts to the state in the database and the user changes are lost. I assume it is the way I am loading the address, which doesn't look correct to me, but it does work when the court information passes validation.

You want to update the attributes in the model objects (but not in the DB) prior to the validation check:

@court = Court.find(params[:id]) @address = @court.address @court.attributes = params[:court] @address.attributes = params[:address] valid = @court.valid? if @address.valid? and valid    @court.save(false) # false = skip validation    @address.save(false)    flash[:notice] = ...    ...

Dan Munk wrote: > Hello, > > I am updating two objects from a form with the code: > > def update > @court = Court.find(params[:id]) > @address = @court.address > > valid = @court.valid? > > if @address.valid? and valid and > @court.update_attributes(params[:court]) and > @address.update_attributes(params[:address]) > flash[:notice] = 'Court was successfully updated.' > redirect_to :action => 'show', :id => @court > else > render :action => 'edit' > end > end > > If the address fails validation I get an error message like I would > expect and the information that the user just keyed is redisplayed to > the user. > > If the court and address both fail validation, the error messages > appear, but the address data reverts to the state in the database and > the user changes are lost. I assume it is the way I am loading the > address, which doesn't look correct to me, but it does work when the > court information passes validation.

You want to update the attributes in the model objects (but not in the DB) prior to the validation check:

I suggest wrapping the whole update in a transaction. It's the only way you can guarantee that multiple objects are (only) updated together, and also a lot easier to get right.

Isak

Great, thanks.