如何在 YML 文件中设置 ActionMailer SMTP 设置?

问题描述 投票:0回答:4

对于我的部署,我更喜欢在

config/
下的 YML 文件中包含所有 Rails 配置选项。我对
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
在这里?我怎样才能确保 actionMailers 配置选项已经加载?

ruby-on-rails configuration actionmailer
4个回答
4
投票

深入挖掘,我发现问题在于

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

仍然,有点丑,但它完成了工作。


2
投票

您可以为此使用

config_for

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

0
投票
Portfolio::Application.config.action_mailer.smtp_settings = config_for(:smtp).symbolize_keys

0
投票

如果你想把它配置得更像Action Storage, by service,你可以这样做。

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
© www.soinside.com 2019 - 2024. All rights reserved.