简体   繁体   English

Rails 4:带参数的around_action

[英]Rails 4: around_action with parameter

In order to drastically reduce code repetition, I want to write up a concern with a generic way to add a special around_action to a controller. 为了大幅减少代码重复,我想用一种通用方法编写一个关注点,向控制器添加一个特殊的around_action It is basically supposed to catch any exception, render the right template and add the exception as a notice. 它基本上应该捕获任何异常,呈现正确的模板并将异常添加为通知。 However, it must be applicable to different actions, and show different templates depending on the action. 但是,它必须适用于不同的操作,并根据操作显示不同的模板。 My goal is basically to be able to do this: 我的目标基本上是能够做到这一点:

protect_from_exception_with 'index', only: [ :update ]

In order to achieve this, I tried to write up my concern like this (Using Rails 4.1): 为了实现这一点,我试着像这样写下我的问题(使用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

However, this leads to an error: 但是,这会导致错误:

LocalJumpError: no block given (yield)

I have trying to find examples for around_action or around_filter with a parameter, but could only find them for before_action . 我试图用参数找到around_actionaround_filter示例,但只能找到它们的before_action

I hope what I'm trying to achieve is at all possible, otherwise I'd need to write a new method in every controller for every action I need to achieve this. 我希望我正在努力实现的目标,否则我需要在每个控制器中为我实现这一目标所需的每个动作编写一个新方法。

There are some clues: 有一些线索:

  1. around_action receives a callback and a block as params, if we send a function as the 1st param, that function mustn't have any parameter! around_action接收callbackblock作为参数,如果我们发送一个function作为第一个参数,该function必须没有任何参数!
  2. We can send a block instead (like you did) but we must pass the current given block to that block as well, your code misses the passing block, that is why the exception raised. 我们可以发送一个块(就像你做的那样)但我们必须将当前给定的块传递给该块,你的代码错过了传递块,这就是引发异常的原因。
  3. In protect_from_exception_with , I can call block_given? protect_from_exception_with ,我可以调用block_given? , it returns true , but I don't know how to get the block out! ,它返回true ,但我不知道怎么把块拿出来!

This works: 这有效:

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

Thankfully, we still have the params in catch_exception_with , make it easy, call the action back to the controller! 值得庆幸的是,我们仍然在catch_exception_with有参数,让它变得简单,将操作调回控制器!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM