类方法定义为实例方法

时间:2015-06-25 15:08:13

标签: ruby-on-rails ruby

这是Michael Hartle的一本工作代码。这是app/mailers/user_mailer.rb中用于为用户帐户创建激活邮件的邮件程序代码:

class UserMailer < ActionMailer::Base
  def account_activation(user)
    @user = user
    mail to: user.email, subject: "Account activation"
  end
end

使用test/mailers/previews/user_mailer_preview.rb中的ruby文件生成邮件预览:

class UserMailerPreview < ActionMailer::Preview
  def account_activation
    user = User.first
    user.activation_token = User.new_token
    UserMailer.account_activation(user)
  end
end

account_activation方法被定义为user_mailer.rb中的实例方法。但它在预览生成器中用作类方法。我是否误解了代码或是否还有其他问题?

对任何有同样疑问的人

这就是ActionMailer的工作方式。电子邮件被定义为扩展ActionMailer::Base的类中的实例方法,但您可以将它们作为类方法访问。

2 个答案:

答案 0 :(得分:3)

ActionMailer的工作原理。电子邮件被定义为扩展ActionMailer::Base的类中的实例方法,但您可以将它们作为类方法访问。

class MyMailer < ActionMailer::Base
  def my_email
  end
end

MyMailer.my_email
# and not MyMailer.new.my_email

这是一个快捷方式,它将实例化ActionMailer类的实例,调用相应的电子邮件方法并返回电子邮件消息。这是the code that handles the call

答案 1 :(得分:0)

魔术背后是deliver/deliver_now/deliver_later(或任何其他交付方式):

def deliver_now
  processed_mailer.handle_exceptions do
    message.deliver
  end
end

看起来 processed_mailer 是我们正在寻找的关键方法:

def processed_mailer
  @processed_mailer ||= @mailer_class.new.tap do |mailer|
    mailer.process @action, *@args
  end
end

此方法创建邮件程序的实例,使用 @action 参数(实例方法的名称)和 @args(传递给类方法的参数)调用 process 方法和最后它返回创建的邮件程序实例。

这就是邮件程序方法被声明为实例方法但被调用为类方法的原因。

快乐学习:)