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

lus*_*eer 6 ruby ruby-on-rails 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
Run Code Online (Sandbox Code Playgroud)

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

谢谢!

Gre*_*vis 4

在我回答你的问题之前:在你的情况下使用 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
Run Code Online (Sandbox Code Playgroud)

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

class ApplicationMailer < ActionMailer::Base
  def send_action(method_name, *args)
    @action_args = args
    super
  end
end
Run Code Online (Sandbox Code Playgroud)

这些参数将在您的所有邮件中提供@action_args