2016-01-22 72 views
1

around_action爲了大幅度減少代碼重複,我想要寫了一個特殊around_action添加到控制器的通用的方式值得關注。它基本上應該是捕捉任何異常,渲染正確的模板並添加異常作爲通知。但是,它必須適用於不同的操作,並根據操作顯示不同的模板。我的目標是基本上能夠做到這一點:軌道4:用參數

protect_from_exception_with 'index', only: [ :update ] 

爲了實現這一點,我試着寫我的關心就像這樣(用Rails 4.1):

module CatchException 
    extend ActiveSupport::Concern 

    module ClassMethods 
    def protect_from_exception_with(failure_template, params) 
     around_action -> { catch_exception_with(failure_template) }, params 
    end 
    end 

    private 

    def log_error(e) 
    # Many things happen here 
    end 

    def catch_exception_with(failure_template) 
    yield 
    rescue => e 
    log_error(e) 
    render failure_template 
    end 
end 

然而,這導致一個錯誤:

LocalJumpError: no block given (yield) 

我一直試圖找到around_actionaround_filter帶有參數的例子,但只能找到他們before_action

我希望我努力實現的是所有可能的,否則我需要在每個控制器中編寫一個新的方法來實現這個目標。

+0

'catch_exception_with'需要採取一個塊,你需要傳遞一個塊到'around_action'了。 – fylooi

+0

@fylooi我數字一樣多,但我無法弄清楚如何做到這一點。我不是一個真正的紅寶石巫師。 – Lanbo

+0

有趣的是,它似乎是爲我工作用'protect_from_exception_with(編輯,只:表演)' – fylooi

回答

3

有一些線索:

  1. around_action收到callbackblock作爲參數,可以如果我們發送一個function作爲第1 PARAM,那function不得有任何參數!
  2. 我們可以把塊,而不是(像你這樣),但我們必須在當前給定塊傳遞給該塊爲好,你的代碼錯過了傳球塊,這就是爲什麼發生異常。
  3. protect_from_exception_with,我可以叫block_given?,它返回true,但我不知道怎麼弄塊了!

這工作:

module CatchException 
    extend ActiveSupport::Concern 

    module ClassMethods 
    def protect_from_exception_with(failure_template, params) 
     around_action -> { catch_exception_with(failure_template) }, params 
    end 
    end 

    private 

    def log_error(e) 
    # Many things happen here 
    end 

    def catch_exception_with(failure_template) 
    self.send(params[:action]) 
    rescue => e 
    log_error(e) 
    render failure_template 
    end 
end 

值得慶幸的是,我們仍然有PARAMS在catch_exception_with,可以很容易,調用動作回控制器!

+0

不幸的是,當我在控制器中多次使用'protect_from_exception_with'時,這將不起作用。 – Lanbo

+0

@LambdaDusk:這很有趣!我更新了一些線索,並仍在尋找更好的解決辦法:) –

+0

@LambdaDusk:檢查新更新的解決方案了,現在好多了! –