Rails 4 ActionMailer around_action |访问操作信息(action_name& parameters)

时间:2016-06-06 16:02:09

标签: ruby-on-rails ruby ruby-on-rails-4

我正在为around_action课程建立customer_mailer,这样我每次拨打begin and rescue

时都不必包裹deliver_now
class CustomerMailer < ApplicationMailer
  around_action :rescue_error

  def send_email(customer)
    ...
  end

  def invite_friend(customer, invitee_email)
    ...
  end

  private
    def rescue_error
      yield
    rescue => e
      msg = "Caught exception! #{e} | #{action_name}"
      puts msg
      raise
     end
end

所以在救援中,我想记录消息,例如调用了哪个动作,我设法找到方法action_name来显示调用了哪个动作,但我找不到办法检索传递给动作的参数,任何想法?

谢谢!

3 个答案:

答案 0 :(得分:3)

在我回答你的问题之前:在你的情况下会使用Bugsnag或类似的工作吗?或者rescue_from Exception, with: :exception_handler会为你工作吗? (虽然不允许你再加上例外)

我挖掘了Rails源代码,似乎参数存储在任何地方。它们只是作为splat传递给您的邮件程序类中定义的实例方法。但是,一种存储方式(没有猴子修补)。

邮寄者继承自AbstractController::Base。看下面的代码:

  # Call the action. Override this in a subclass to modify the
  # behavior around processing an action. This, and not #process,
  # is the intended way to override action dispatching.
  #
  # Notice that the first argument is the method to be dispatched
  # which is *not* necessarily the same as the action name.
  def process_action(method_name, *args)
    send_action(method_name, *args)
  end

  # Actually call the method associated with the action. Override
  # this method if you wish to change how action methods are called,
  # not to add additional behavior around it. For example, you would
  # override #send_action if you want to inject arguments into the
  # method.
  alias send_action send

我们可以看到我们可以覆盖#send_action并使其存储参数。将以下内容添加到您的ApplicationMailer

class ApplicationMailer < ActionMailer::Base
  def send_action(method_name, *args)
    @action_args = args
    super
  end
end

参数将在所有邮件中以@action_args的形式提供。

答案 1 :(得分:2)

只需将调用操作的参数存储到实例变量,例如@params。然后,rescue_error可通过@params访问这些参数。根据你的例子:

class CustomerMailer < ApplicationMailer
  around_action :rescue_error

  def send_email(customer)
    @params = { customer: customer }
    ...
  end

  def invite_friend(customer, invitee_email)
    @params = { customer: customer, invitee_email: invitee_email }
    ...
  end

  private

  def rescue_error
    begin
      yield
    rescue => e
      msg = "Caught exception! #{e} | #{action_name} | #{@params.inspect}"
      puts msg
      raise
    end
  end
end

您可以通过在操作中使用哈希参数来使@params的分配更加清晰,例如

def invite_friend(options = {})
  @params = params
  ...
end

当然,这需要通过options访问参数,例如options[:customer]访问customeroptions[:invitee_email]访问invitee_email

答案 2 :(得分:0)

必须产生动作名称,这取决于您使用rescue_error的方式。

在块中定义一个将产生的变量

或引发细节错误(可能是您的自定义异常类) 这样你就可以通过“e”

检索invormation

发布一个例如rescue_error的例子。