2012-03-26 16 views
4

In ActiveRecord Modell after_save Callback muss ich ROLLBACK transaction und false zurückgeben.Return false und rollback in after_save callback

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

Diese Callback-Rollback-Transaktion aber mymodel.save! gibt wahr zurück. Wie kann es false und Rollback zurückgeben?

Antwort

-1

Das glaube ich nicht, dass Sie dies mit after_save tun können Sie bei around_save statt suchen sollte:

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

Rails wickelt 'Model # save' in einer Transaktion trotzdem. Sie sollten keine zweite Transaktion innerhalb des Hooks around_save öffnen. Stattdessen sollten Sie nur 'ActiveRecord :: Rollback' aufrufen. – 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 

Also ... ich around_save kommen denke schon auf einem Transaktionsblock, so dass Sie don 't müssen hinzufügen, dass zusätzliche ActiveRecord :: Base.transaction blockieren, weil Rollbacks nicht propagieren

Also, wenn Sie Rollback vor oder nach der Ausbeute, müssen Sie diese interne Transaktion entfernen.

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: Lesen, was ich schrieb ... scheinen jetzt schwer zu verstehen. Der Punkt ist: Wenn Sie sind gonna aroud_save Gebrauch nicht wieder Wrapp mit ActiveRecord::Base.transaction (wie im letzten Beispiel tun), weil Schienen wird der Anruf zu around_save mit ist eigenen ActiveRecord::Base.transaction so wickeln, wenn Sie raise ActiveRecord::Rollback Sie rollen wieder die interne Transaktion, so können Sie mit Extrangergebnissen und Teilsicherungen enden (wie im ersten Beispiel, das FAIL ist).

5

Wenn Sie ein Speichern in einem after_save Rückruf abbrechen möchten, sollten Sie

raise ActiveRecord::RecordInvalid.new(self) 

statt

raise ActiveRecord::Rollback 

Dies wird nicht nur die Transaktion Rollback (Rückrufe immer in einem possibly- passieren implizite Transaktion als Teil der save oder create) aber auch save zu false zurückgeben. Hier

ist ein Artikel mit mehr Details: http://tech.taskrabbit.com/blog/2013/05/23/rollback-after-save/

Verwandte Themen