views:

208

answers:

2

i have a transaction to ensure two models get saved at the same time.

begin 
  Recipe.transaction do
    @recipe.save!
    if @dish
      @dish.save!
    end
  end
rescue

  #save failed
  flash[:notice] = "recipe.saved = #{@recipe.new_record?}"
  render 'form'
else
  #save worked
  flash[:notice] = 'Recipe added.'
  redirect_to(@recipe)
end

when validation fails for one of the models it goes to the rescue block however in the rescue block it says that the model is not a new record. i was expecting the validation to cause the transaction to fail, thus leaving the model object as a new record? what am i missing here?

+3  A: 

Which of the two saves is actually failing? The one for @recipe or for @dish?

Transactions are handled by your DBMS. So for example, when @dish fails to save, @recipe might've already been saved, but will be reverted by your DBMS. However, this happens behind Rails' back, and so it does not revert the state of the @recipe object.

Shtééf
@dish fails. i didn't realise the transaction happens behind the scenes so the recipe object in this case gets out of sync. thanks.
rogerfed
A: 

I'm fairly certain that the outermost transaction will apply to everything within it -- so in this case, if saving dish failed, the creation of recipe will be rolled back as well.

Maybe you aren't using InnoDB tables? MyISAM does not support transactions.

John