【问题标题】:Rails ActionMailer lib directoryRails ActionMailer 库目录
【发布时间】:2015-09-27 06:51:46
【问题描述】:

我正在尝试从 lib 目录中的文件发送邮件。我使用Action Mailer Basics 来帮助我配置它。我可以从我的控制器成功发送邮件,所以我认为我的问题是我的 lib 文件“filename.rb”中没有正确要求邮件程序。

我运行ruby filename.rb 并得到

/pathtofile/lib/otherfile.rb:37:in `alert': uninitialized constant UserMailer (NameError)
from filename.rb:47:in `block in <main>'
from filename.rb:35:in `secondly_loop'
from filename.rb:47:in `<main>'

文件名.rb

alert

otherfile.rb

def alert
  #send email http://www.gotealeaf.com/blog/handling-emails-in-rails
  UserMailer.mailer_method().deliver_now
  puts "Sent Email"
end #end def alert

app/mailers/user_mailer.rb

class UserMailer < ApplicationMailer
  default from: 'email@email.com'

  def mailer_method(a)
    @a = a
    mail(to: 'email@email.com', subject: "Hello you have new mail")
  end
end

app/views/mailer_method.html.erb

<!DOCTYPE html>
<html>
  <head>
    <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
  </head>
  <body>
    <h2>Daniel, </h2>
    <p>Your email is boring and has arrived now.<br><br>
      Sincerely,<br>
      Daniel</p>
  </body>
</html>

【问题讨论】:

    标签: ruby-on-rails ruby actionmailer


    【解决方案1】:

    Rails 会自动为您加载模型。仅调用 ruby filename.rb 不会为您加载 UserMailer,因此您将收到 uninitialized constant 错误,因为当前命名空间中没有定义 UserMailer

    EDIT 这是一个允许您调用alert 的SSCCE:注意它位于MyAlert 的命名空间内; Rails 自动加载了UserMailer,因此它可以在MyAlert 的命名空间中访问。

    为了简洁明了,我稍微更改了一些定义。

    my_alerts.rb

    class MyAlerts
      def self.alert
        UserMailer.mailer_method("It worked")
        puts "Sent Email"
      end 
    end
    

    application_mailer.rb

    class ApplicationMailer < ActionMailer::Base
      default from: "from@example.com"
      layout 'mailer'
    end
    

    user_mailer.rb

    class UserMailer < ApplicationMailer
      default from: 'email@email.com'
    
      def self.mailer_method(a)
        puts a
      end
    end
    

    输出:

    lbrito@lbrito:~/Documents/rails/textgen$ rails c
    Loading development environment (Rails 4.2.4)
    2.2.1 :001 > MyAlerts.alert
    It worked
    Sent Email
     => nil 
    

    【讨论】:

    • 我不知道如何调用alert,即使它在rails console 中工作,我也不明白rails 如何与lib 交互
    • @Daniel 我提供了一个 SSCCE,希望能让事情变得清晰。
    • 它确实有很大帮助,但我仍然收到相同的错误消息。我什至这样做了:
    • filename.rb => MyAlerts.alert 我重新组织了我的代码以包含您建议的更改。我需要有一个 cron 作业调用 ruby filename.rb 我想我可以让一个 cron 作业运行 MyAlerts.alert 代替.... 有没有调用 ruby filename.rb 并加载邮件?
    • 让另一个进程调用ruby filename.rb 会导致我提到的同样问题:执行alert 时,UserMailer 未定义。我建议你使用 Resque (github.com/resque/resque) 之类的工具在 Rails 中执行 cron 作业。
    【解决方案2】:

    这是使用 require 的更新示例。注意我不建议实际这样做,因为这应该设置为 rake 任务,所以这纯粹是使用 require 的示例:

    lib/filename.rb

    #!/usr/bin/env ruby
    
    require_relative './my_alert'
    
    MyAlert.alert
    

    lib/my_alert.rb

    require_relative '../app/mailers/user_mailer'
    
    class MyAlert
      def self.alert
        #send email
        UserMailer.mailer_method("foo").deliver_now
        puts "Sent Email"
      end
    end
    

    app/mailers/user_mailer.rb

    require 'action_mailer'
    
    class UserMailer < ActionMailer::Base
      default from: 'email@email.com'
    
      def mailer_method(a)
        @a = a
        mail(to: "mail@email.com", subject: "Hello you have new mail")
      end
    end
    

    我已经让它在测试应用程序中工作,以便它可以访问 UserMailer,但由于它实际上并没有作为 Rails 应用程序运行,因此您需要添加更多代码让 ActionMailer 知道在哪里查找模板.制作一个 rake 任务实际上将通过 Rails 运行它,这是首选。

    【讨论】:

    • 我无法让任何 require/require_relative '../app/mailers/user_mailer.rb' 组合工作
    • 当您需要时,您需要省略 .rb 扩展名,因此,您将使用:require_relative '../app/mailers/user_mailer' NOT require_relative '../app/mailers/user_mailer。 rb'
    • 当我之前尝试过时,我尝试过 require/require_relative 和 '../app/mailers/user_mailer' 或 '~/app/mailers/user_mailer' 'user_mailer' 的各种组合(有和没有.rb) .... 我认为 12 种组合
    • @Daniel 如果您希望能够从命令行调用 UserMailer,您应该定义一个 rake 任务,这样您就可以运行 rake 任务而不是尝试直接调用 ruby​​ 脚本。参见示例:stackoverflow.com/questions/21456886/…
    • 感谢好建议,它看起来是一个很好的解决方案;我可以使用 cron 作业来调用 rake 命令。我会用它来让它工作。但是它仍然没有回答我提出的问题。你知道为什么你可能无法从 lib 内部调用 UserMailer 吗?
    【解决方案3】:

    如果您使用的是 rails lib 文件夹,那么您应该使用 rails 来运行您的代码。您正在尝试运行包含 rails 上下文之外的 rails 组件的 ruby​​ 代码。当您运行ruby filename.rb 时,您将传递所有进入rails 自动加载的魔力。 ActionMailer 是一个 gem,当你运行你的 rails 服务器时,通常会通过 bundler 为你加载这个 gem。查看您的config/applicarion.rb 以了解我在做什么。如果您仍然感到困惑,请阅读:http://guides.rubyonrails.org/autoloading_and_reloading_constants.html

    我认为您想要做的是构建一个 Rails 引擎。这样,您可以保持代码模块化,但仍然可以访问所有各种 Rails 组件和 gem,例如 ActionMailer。有一百万个关于如何构建 Rails 引擎的精彩教程来帮助您入门,但我会从阅读 ruby​​ on rails 官方指南开始。

    【讨论】:

      猜你喜欢
      • 2011-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多