2012-03-26 18 views
4

ActiveRecordモデルafter_saveコールバックでは、トランザクションをROLLBACKしてfalseを返す必要があります。after_saveコールバックでfalseとrollbackを返す

def after_save_callback 
    if mycondition? 
    raise ActiveRecord::Rollback 
    end 
end 

このコールバックロールバックトランザクションですが、mymodel.save! trueを返します。それを虚偽とロールバックに戻す方法は?

答えて

-1

私はあなたが代わりにaround_saveされているはずです、あなたがafter_saveでこれを行うことができるとは思わない:

def around_save 
    ActiveRecord::Base.transaction do 
    yield # calls the actual save method 
    raise ActiveRecord::Rollback if my_condition? 
    end 
end 
+6

Railsはとにかくトランザクション内の 'モデル#save'をラップします。 around_saveフック内で2番目のトランザクションを開くべきではありません。むしろ 'ActiveRecord :: Rollback'を呼び出すだけです。 – BBonifield

4
def around_save 
    ActiveRecord::Base.transaction do 
    raise ActiveRecord::Rollback # this will actually ROLLBACK 
    yield # calls the actual save method 
    raise ActiveRecord::Rollback # this will cause a COMMIT!!! because it affect only this internal transaction. 
    # OTHER ACTIONS NOT EXECUTED BUT BEING A INTERNAL TRANSACTION, THE PARENT WILL COMMIT, because parent hasn't failed. 
    end 
end 

だから... ...私は、あなたドンので、around_saveトランザクションブロックにすでに来ると思いますその余分なActiveRecord :: Base.transaction doブロックを追加する必要はありません。ロールバックは伝播しないため

したがって、前回または後にロールバックする場合は、その内部トランザクションを削除する必要があります。

def around_save 
    #ActiveRecord::Base.transaction do 
    raise ActiveRecord::Rollback # this will actually ROLLBACK 
    yield # calls the actual save method 
    raise ActiveRecord::Rollback # this will actually ROLLBACK 
    # end 
end 

EDIT:は私が書いたものを読んで...今理解するのが難しいようです。ポイントは次のとおりです。あなたがレールにaround_saveへの呼び出しをラップするため、(は、最後の例のように行う)を使用aroud_saveActiveRecord::Base.transaction再びwrappしていないつもりであれば自分でActiveRecord::Base.transactionので、あなたが唯一のロールバックされraise ActiveRecord::Rollbackときに最も内部トランザクションであるため、(最初の例のように)FAILのように、結果と部分的な保存で終わることができます。あなたはafter_saveコールバックで保存中止したい場合は

5

、あなたが

raise ActiveRecord::RecordInvalid.new(self) 

ではなく

raise ActiveRecord::Rollback 

これが唯一のトランザクションをロールバックしません必要があります(コールバックは常にpossibly-内部で起こりますsaveまたはcreateの一部としての暗黙のトランザクション)、savefalseを返す原因となります。ここで

は、より多くの詳細を記事です:http://tech.taskrabbit.com/blog/2013/05/23/rollback-after-save/

関連する問題