ruby-on-rails 如何在YML文件中设置ActionMailer SMTP设置?

r55awzrz  于 2023-05-19  发布在  Ruby
关注(0)|答案(4)|浏览(154)

对于我的部署,我更喜欢将所有Rails配置选项放在config/下的YML文件中。我对action_mailer.smtp_settings有特殊的问题。
文件名:config/smtp.yml

development:
  address: localhost
  port: 1025

test:

production:
  address: smtp.xs4all.nl
  port: 465
  authentication: plain
  user_name: xxxxx
  password: xxxxx
  tls: true

然后我尝试通过初始化器包含这些值。config/initializers/smtp.rb

options = YAML.load_file(Rails.root.join('config', 'smtp.yml'))[Rails.env]

options.each do |name, value|
  Portfolio::Application.config.action_mailer.smtp_settings[name.to_sym] = value
end unless options.nil?

这将加载smtp.yml文件,解析该文件并返回当前环境的散列,例如

{"address"=>"smtp.xs4all.nl", "port"=>465, "authentication"=>"plain", "user_name"=>"xxxxx", "password"=>"xxxxx", "tls"=>true}

将键转换为符号,并将其添加到smtp设置中,结果如下:

irb(main):002:0> Portfolio::Application.config.action_mailer.smtp_settings
  => {:port=>465, :address=>"smtp.xs4all.nl", :authentication=>"plain", :user_name=>"xxxxx", :password=>"xxxx", :tls=>true}

但是当部署到生产环境时,这会导致一些冲突,可能是因为某些部分尚未引导。Capistrano失败:

* executing "cd -- /var/www/ANT_cms/releases/20131218170336 && bundle exec rake RAILS_ENV=production RAILS_GROUPS=assets assets:precompile"
servers: ["li153-5.members.linode.com"]
[li153-5.members.linode.com] executing command
 ** [out :: li153-5.members.linode.com] rake aborted!
 ** [out :: li153-5.members.linode.com] undefined method `[]=' for nil:NilClass

为什么我的Portfolio::Application.config.action_mailer.smtp_settings nil在这里?如何确保actionMailers配置选项已加载?

u0sqgete

u0sqgete1#

深入挖掘,我发现问题是bundle exec rake RAILS_ENV=production RAILS_GROUPS=assets assets:precompile"只加载了一小部分,而不是例如。ActionMailer
在我的加载器中添加一个早期退出修复了config/initializers/smtp.rb中的这个问题:

unless Portfolio::Application.config.action_mailer.nil?

  options = YAML.load_file(Rails.root.join('config', 'smtp.yml'))[Rails.env]

  options.each do |name, value|
    Portfolio::Application.config.action_mailer.smtp_settings[name.to_sym] = value
  end unless options.nil?

end

然后,下一个问题是,在生产环境中设置了action_mailer,但smtp_settings不必定义和填充默认值。因此,用空哈希预填充这个问题解决了整个问题:

unless Portfolio::Application.config.action_mailer.nil?

  Portfolio::Application.config.action_mailer.smtp_settings = {}

  options = YAML.load_file(Rails.root.join('config', 'smtp.yml'))[Rails.env]

  options.each do |name, value|
    Portfolio::Application.config.action_mailer.smtp_settings[name.to_sym] = value
  end unless options.nil?
end

尽管如此,有点丑陋,但它确实起到了作用。

yvt65v4c

yvt65v4c2#

你可以使用config_for来实现:

Portfolio::Application.config.action_mailer.smtp_settings = config_for(:smtp)
hvvq6cgz

hvvq6cgz3#

Portfolio::Application.config.action_mailer.smtp_settings = config_for(:smtp).symbolize_keys
c9x0cxw0

c9x0cxw04#

如果您想按服务更像操作存储那样配置它,您可以这样做。
config/mailer.yml

sendgrid: 
  user_name: apikey
  password: "<%= ENV.fetch("SENDGRIP_API_KEY") %>"
  address: smtp.sendgrid.net
  port: 587
  authentication: :plain
  enable_starttls_auto: true

gmail:
  user_name: xxxxx
  password: "<%= ENV.fetch("GMAIL_APP_PASSWORD") %>"
  address: smtp.gmail.com
  port: 587
  authentication: :plain
  enable_starttls_auto: true
  open_timeout: 5
  read_timeout: 5

app/lib/mail/gmail_smtp.rb

class GmailSmtp < Mail::SMTP; end

config/initializers/mailer.rb

Rails.application.configure do
  config_file = Rails.root.join("config/mailer.yml")
  action_mailer_config = ActiveSupport::ConfigurationFile.parse(config_file).deep_symbolize_keys

  # Default for all mailers
  config.action_mailer.smtp_settings = action_mailer_config[:sendgrid]
  
  config.action_mailer.gmail_smtp_settings = action_mailer_config[:gmail]
end

app/mailers/user_mailer.rb

class UserMailer < ApplicationMailer
  default delivery_method: :gmail_smtp

  def my_notification
  end
end

相关问题