了解 Rails ActionMailer 编码

Understanding Rails ActionMailer coding

我对 ActionMailer 编码有点困惑。

一个标准动作邮件示例

app/mailers/example_mailer.rb

class ExampleMailer < ActionMailer::Base
  default from: "from@example.com"

  def sample_email(user)
    @user = user
    mail(to: @user.email, subject: 'Sample Email')
  end
end

app/controllers/users_controller.rb

def create
  @user = User.new(user_params)

  respond_to do |format|
    if @user.save

      # Sends email to user when user is created.
      ExampleMailer.sample_email(@user).deliver_now

      format.html { redirect_to @user, notice: 'User was successfully created.' }
      format.json { render :show, status: :created, location: @user }
    else
      format.html { render :new }
      format.json { render json: @user.errors, status: :unprocessable_entity }
    end
  end
end

我的问题与

有关
ExampleMailer.sample_email(@user).deliver_now
  1. 如何在没有 ExampleMailer.new 的情况下 ExampleMailer 访问 sample_email 方法? sample_email 不是 class 方法!

  2. 如何deliver_now调用ExampleMailer

我希望这是清楚的。任何帮助表示赞赏。

你是对的 sample_email 不是 class 方法,它是一个实例方法。但是 ExampleMailer 继承自 ActionMailer::Base,后者进行了一些巧妙的元编程。

当您调用 ExampleMailer.simple_email 时,它没有找到 class 方法,因此会自动调用私有方法 method_missing

method_missing中它检查实例方法是否存在,创建一个邮件程序实例对象(所以它基本上为你做了.new),调用邮件程序对象的实例方法,然后returns 对象...并且在该对象上,您调用了 deliver_nowdeliver_later 方法,因为您在原始行中指定了这些方法。基本上和你做的一样...

my_mail_thing = ExampleMailer.sample_email(@user)
my_mail_thing.deliver_now

但是,如果 ExampleMailer 找不到实例方法,它会返回标准缺失响应,例如"NoMetihodError:: undefined method 'another_simple_email' for ExampleMail.:Class"

一切都很棒。您可以通过谷歌搜索该术语来了解更多关于 method_missing 的信息,并且您可以自己进行实验 class。