保存失败后Rails没有回滚事务()(Rails not rolling back transaction after failed save())
我有这个域模型:用户有一组项目,项目的状态可能无法通过验证。
验证工作正常,我甚至看到当我使用
save!
时调用异常save!
。在我的控制器中,我有这个:
@user.items() << item if @user.save render :json => {}, :status => :ok else render :json => {:status => :error, :errors => item.errors}, :status => :bad_request end
第一个POST成功,第二个POST失败,但是当我点击索引时,我仍然看到两个对象,好像第二个事务从未回滚过。 到底是怎么回事?
我的测试是这样的:
post :create post :create get :index ActiveSupport::JSON.decode(response.body).length.should == 1
编辑:即使在运行服务器时,也不会回滚事务(sqlite3)。
I have this domain model: A user has group of items, and the state of the items can fail a validation.
Validation works fine, and I even see exceptions get called when I use
save!
.In my controller, I have this:
@user.items() << item if @user.save render :json => {}, :status => :ok else render :json => {:status => :error, :errors => item.errors}, :status => :bad_request end
The first POST succeeds, and the second POST fails, but when I hit the index, I still see two objects, as if the second transaction never rolled back. What is going on?
My test is this:
post :create post :create get :index ActiveSupport::JSON.decode(response.body).length.should == 1
Edit: Even when running a server, transactions are not being rolled back (sqlite3).
原文:https://stackoverflow.com/questions/14665269
最满意答案
将项添加到集合会立即保存它(除非用户未保存)。 对save的调用会创建自己的事务,即回滚的事务,而不是保存项目的事务
您可以通过显式创建一个来强制所有事务进入同一事务。
begin User.transaction do @user.items << item @user.save! render :json => {}, :status => :ok end rescue ActiveRecord::RecordInvalid render :json => {:status => :error, :errors => item.errors}, :status => :bad_request end
Adding an item to the collection saves it immediately (unless the user is unsaved). The call to save creates its own transaction and that is what is rolled back, not the transaction in which the item is saved
You could force everything into the same transaction by creating one explicitly.
begin User.transaction do @user.items << item @user.save! render :json => {}, :status => :ok end rescue ActiveRecord::RecordInvalid render :json => {:status => :error, :errors => item.errors}, :status => :bad_request end