1

create是一種方法,只有當所有事情按預期發生時才返回true,否則返回false。我正在尋找錯誤代碼樣式控制流程。返回內部交易和ActiveRecord ::回滾

class TransferOperator 
    class TransferError < Struct.new(:type, :message); ; end 

    attr_reader :transfer, :error 

    def initialize(transfer) 
    @transfer = transfer 
    end 

    # Creates the transfer and locks money in the bank 
    def create 
    return error(:validation_error) if transfer.invalid? 

    to_bank = transfer.main_to_bank 
    to_bank.with_lock do 
     # How does return here behave? Should a raise be issued instead and caught outside? 
     return error(:insufficient_buffer) if to_bank.available_balance < transfer.amount 
     to_bank.available_balance -= transfer.amount 
     to_bank.locked_balance += transfer.amount 
     to_bank.save! 
     transfer.save! 
    end 

    # Is it guaranteed here that the above transaction has always been succesful? 
    true 
    end 

    private 

    def error(type, message='') 
    @error = TransferError.new(type, message) 
    false 
    end 
end 

這裏的想法是讓呼叫者這樣一個流程:

def move_money 
    @transfer = Transfer.new(params) 
    operator = TransferOperator.new(@transfer) 
    if operator.create 
    redirect_to :root, notice: 'success!' 
    else 
    if operator.error.type == :validation_error 
     render action: 'new' 
    elsif operator.error.type == :insufficient_buffer 
     redirect_to :root, notice: 'not enough money' 
    else 
     # Handle other errors here... 
    end 
    end 
end 

與事務中返回的錯誤會發生什麼?

它保證交易成功,如果返回true?

http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html

一個例外是的ActiveRecord ::回滾異常,引發時將 觸發回滾,而不是由 事務塊重新提出。

有沒有可能Rails自己提高ActiveRecord::Rollback?如果是這樣,那麼交易將默默地失敗,並且真實地返回(這不是我們想要的)。

回答

2

如果要使事務回滾,則必須引發錯誤。您有幾個選擇:

  1. 提高ActiveRecord::Rollback並且事務將被回滾並且不會在事務塊外重新生成錯誤。正如你所說,這將悄悄地回滾交易。可能不是你想要的。
  2. 引發任何其他類型的錯誤。這會導致事務回滾,並且會引發錯誤。您可以挽救該錯誤以適當地重定向用戶。

返回一個錯誤對象什麼也不做。這只是另一個傳遞的對象。

+0

我們可以指望Rails沒有提高'ActiveRecord :: Rollback'本身_在事務處理? – randomguy 2014-10-06 22:25:51

+1

Rails永遠不會引發一個'ActiveRecord :: Rollback'本身。那麼,技術Rails內部使用這個錯誤,但它不會在你的事務塊中引發它。 – infused 2014-10-06 22:27:38