繁体   English   中英

`method_missing':Emailer:Class 的未定义方法 `mail'(NoMethodError)

[英]`method_missing': undefined method `mail' for Emailer:Class (NoMethodError)

我正在学习 Peter Cooper 的书 Beginning Ruby。
其中有一个使用 ActionMailer 发送电子邮件的简单示例。 示例代码如下:

require 'action_mailer'

ActionMailer::Base.smtp_settings = {
    :address => "smtp.mail.yahoo.com",
    :port => 465,
    :authentication => :login,
    :user_name => "username@yahoo.com",
    :password => "password",
    :openssl_verify_mode => :ssl
}

class Emailer < ActionMailer::Base
  def self.test_email(email_address, email_body)
    mail(to: email_address, from: 'username@yahoo.com', subject: 'action mailer test', body: email_body)
  end
end

Emailer.test_email('username@gmail.com', 'This is a test e-mail!').deliver_now

如您所见,我想使用 yahoo 的 smtp 服务器向我的 gmail 帐户发送电子邮件。 我向 ActionMailer::Base 提供了所需的smtp 设置并创建了类方法test_email以使用main方法和deliver_now方法发送电子邮件。 但是我收到以下错误消息:

/home/asarluhi/.rvm/gems/ruby-2.5.1@beginning_ruby/gems/actionmailer-5.2.0/lib/action_mailer/base.rb:582:in `method_missing': undefined method `mail' for Emailer:Class (NoMethodError)

我还尝试将test_email方法更改为实例方法并使用Emailer.new.test_email ...在这种情况下,我收到的错误消息是:

/home/asarluhi/.rvm/gems/ruby-2.5.1@beginning_ruby/gems/mail-2.7.0/lib/mail/message.rb:1396:in `method_missing': undefined method `deliver_now' for #<Mail::Message:0x0000000002e0eac8> (NoMethodError)

我不知道为什么方法mail先然后方法deliver_now不被识别,而是属于 Ruby 5.2.0 中的ActionMailer::Base 的两种方法。

——编辑——
如果我从test_email方法中删除self ,因为它最初在书中(我认为这是一个错误),当我运行包含上述代码的 rb 文件时,我会收到一个很长的回溯(21 行),并显示以下错误消息:

/home/asarluhi/.rvm/rubies/ruby-2.5.1/lib/ruby/2.5.0/net/protocol.rb:189:in `rbuf_fill': end of file reached (EOFError)

据作者介绍,ActionMailer 可以独立于 Rails 使用。 所以我在专用的 rvm gemset 中安装了 ActionMailer gem,并将上面的代码写在rb文件中,代码从书中提取。 运行这个脚本我收到 EOFError 错误。 我所有使它工作的尝试,例如将self添加到test_email方法或在类 Emailer 的实例上调用方法test_email失败了。

问题是使用“自我”。 必须是

def test_email(email_address, email_body)
  ...
end

代替

def self.test_email(email_address, email_body)
  ...
end

因此, Emailer.test_email.deliver_now将起作用。 文档中,我们可以看到mail是实例方法,但在self.method_name只有类方法可用。 类方法是属于该类但不绑定到任何特定单个实例的功能。 反义词也是公平的。 为什么是Emailer实例而不是类? 来自 ActionMailer::Base 的魔法

没有要检查的 yahoo 帐户,但此配置适用于我的 gmail 帐户:

require 'action_mailer'

ActionMailer::Base.delivery_method = :smtp
ActionMailer::Base.smtp_settings = {
    :address => "smtp.gmail.com",
    :port => 587,
    :authentication => :plain,
    :user_name => "sender@gmail.com",
    :password => "<password>",
    :enable_starttls_auto => true
}


class Emailer < ActionMailer::Base
  def test_email(email_address, email_body)
    mail(to: email_address, from: 'sender@gmail.com', subject: 'action mailer test', body: email_body)
  end
end

Emailer.test_email('recipient@gmail.com', 'This is a test e-mail!').deliver_now

可能导致此错误消息的一种方法是,如果您只是使用了错误的命名空间,例如我有

AlertsMailer.new_user_signup(user).deliver_now

但对我来说应该是

MessagesMailer.new_user_signup(user).deliver_now

因此 rails 找不到该命名空间的方法。 正如我所了解的那样,仔细检查您的代码是值得的:)

暂无
暂无

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

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