2016-01-22 78 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:检查新更新的解决方案了,现在好多了! –