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 开发者_Python百科to fail, thus leaving the model object as a new record? what am i missing here?
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.
From the Rails documentation:
Exceptions will force a ROLLBACK that returns the database to the state before the transaction began. Be aware, though, that the objects will not have their instance data returned to their pre-transactional state.
http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html
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.
精彩评论