简体   繁体   English

定义为实例方法的类方法

[英]Class methods defined as instance methods

This is a working code from the Michael Hartle book.这是 Michael Hartle 书中的工作代码。 This is the mailer code in app/mailers/user_mailer.rb to create an activation mail for a user account:这是app/mailers/user_mailer.rb的邮件程序代码,用于为用户帐户创建激活邮件:

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

The preview of the mail is generated using the ruby file in test/mailers/previews/user_mailer_preview.rb :邮件的预览是使用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

The account_activation method is defined as an instance method in user_mailer.rb . account_activation方法被定义为user_mailer.rb一个实例方法。 But it is used in preview generator as a class method.但它在预览生成器中用作类方法。 Did I misunderstand the code or is there something else going on here?我误解了代码还是这里发生了其他事情?

To anyone who have the same doubt致有同样疑问的人

That's how ActionMailer works.这就是 ActionMailer 的工作方式。 Emails are defined as instance method in a class that extends ActionMailer::Base , but you access them as class methods.电子邮件在扩展ActionMailer::Base的类中被定义为实例方法,但您可以作为类方法访问它们。

That's how ActionMailer works.这就是ActionMailer工作方式。 Emails are defined as instance method in a class that extends ActionMailer::Base , but you access them as class methods.电子邮件在扩展ActionMailer::Base的类中被定义为实例方法,但您可以作为类方法访问它们。

class MyMailer < ActionMailer::Base
  def my_email
  end
end

MyMailer.my_email
# and not MyMailer.new.my_email

This is a shortcut that will instantiate an instance of the ActionMailer class, invoke the corresponding email method and return an email message.这是一个快捷方式,它将实例化 ActionMailer 类的实例,调用相应的电子邮件方法并返回电子邮件消息。 This is the code that handles the call .这是处理调用的代码

The Magic is behind deliver/deliver_now/deliver_later (or any other deliver method):魔术背后是deliver/deliver_now/deliver_later (或任何其他交付方法):

def deliver_now
  processed_mailer.handle_exceptions do
    message.deliver
  end
end

Looks like processed_mailer is the key method that we were looking for:看起来processed_mailer是我们正在寻找的关键方法:

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

This method creates the instance of the mailer, calls process method with @action argument (which is the name of the instance method) and with @args , which are the arguments passed to the class method and in the end it returns the created instance of the mailer.此方法创建邮件程序的实例,使用@action参数(实例方法的名称)和@args调用 process 方法, @action参数是传递给类方法的参数,最后它返回创建的实例邮递员。

So thats the reason that mailer methods are being declared like instance ones but get called like class ones.所以这就是邮件方法被声明为实例方法但被调用为类方法的原因。

Happy Learning :)快乐学习:)

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

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