ruby-on-rails - `method_missing':Emailer:Class (NoMethodError) 的未定义方法 `mail'
问题描述
我正在研究 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
first 然后 methoddeliver_now
不被识别,而是两个方法都属于Ruby 5.2.0 中的ActionMailer::Base。
--- 已编辑 --
如果我self
从test_email
方法中删除,因为它最初在书中(我认为这是一个错误),当我运行包含上述代码的 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 使用。所以我将 ActionMailer gem 安装在一个专用的 rvm gemset 中,并将上面的代码写在一个rb
文件中,代码摘自书中。运行此脚本我收到 EOFError 错误。我所有使它工作的尝试,例如添加self
到test_email
方法或调用test_email
类 Emailer 实例的方法都失败了。
解决方案
问题是使用“自我”。一定是
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 的魔法
推荐阅读
- android - 应该在哪里调用后端 API - 在用例中还是在存储库中?
- python - 如何查找 GPS 坐标是否位于特定道路上
- typescript - 如何使 TypeScript 通用约束应用于函数定义?
- c# - C#构造ISerializable接口的正确方法?
- python - 如何通过 librosa 转置部分声音
- git - 当我在 Github 上托管 Flutter Web 应用程序时,什么也没有出现
- reactjs - KeyboardDatePicker 灰色天数
- java - Java Swing注册表单密码弱点情况
- java - 错误:JNINativeMethod nfptr 抛出从 jobjectarray* 到 void* 的无效转换
- sql - 如何使数组从laravel中的数据库中获取数据