`method_missing': Emailer:Class 的未定义方法 `mail' (NoMethodError)
`method_missing': undefined method `mail' for Emailer:Class (NoMethodError)
我正在研究 Peter Cooper 的书《开始》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 setting 并创建了 class 方法 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 和方法 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
方法或在 class Emailer 的实例上调用方法 test_email
失败。
问题是使用 'self'。必须
def test_email(email_address, email_body)
...
end
而不是
def self.test_email(email_address, email_body)
...
end
所以,Emailer.test_email.deliver_now
会起作用。 docs 我们可以看到 mail
是实例方法,但在 self.method_name
中只有 class 方法可用。 Class 方法是属于 class 但不依赖于任何特定的单个实例的功能。相反的说法也很公平。
为什么是 Emailer
实例而不是 class?来自ActionMailer::Base
的魔法
没有要检查的雅虎帐户,但 this configuration 已使用我的 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 找不到该命名空间的方法。据我所知,仔细检查你的代码是值得的:)
我正在研究 Peter Cooper 的书《开始》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 setting 并创建了 class 方法 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 和方法 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
方法或在 class Emailer 的实例上调用方法 test_email
失败。
问题是使用 'self'。必须
def test_email(email_address, email_body)
...
end
而不是
def self.test_email(email_address, email_body)
...
end
所以,Emailer.test_email.deliver_now
会起作用。 docs 我们可以看到 mail
是实例方法,但在 self.method_name
中只有 class 方法可用。 Class 方法是属于 class 但不依赖于任何特定的单个实例的功能。相反的说法也很公平。
为什么是 Emailer
实例而不是 class?来自ActionMailer::Base
没有要检查的雅虎帐户,但 this configuration 已使用我的 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 找不到该命名空间的方法。据我所知,仔细检查你的代码是值得的:)