ActionMailer 的 default_url_options:如何从 DefaultOptions 自动检索端口?

2024-02-23

我经常并行运行许多 Rails 应用程序,因此我将它们配置为使用不同的端口:

# Change default port of development server, see http://stackoverflow.com/questions/18103316
require 'rails/commands/server'
module DefaultOptions
  def default_options
    super.merge!(Port: 3001)
  end
end

现在重要的是,这也适用于开发环境中的 ActionMailer:

config.action_mailer.default_url_options = {host: 'localhost:3001'}

但我不想对其进行硬编码,而是直接从DefaultOptions。这怎么可能?


这是与您的代码的一个小偏差:

# config/boot.rb
require 'rails/commands/server'
module DefaultOptions
  PORT = 3001

  def default_options
    super.merge!(Port: PORT)
  end
end

# This line was part of the Stack Overflow answer you quoted, and is important
# With newer Ruby versions, you can call `prepend` directly
Rails::Server.prepend(DefaultOptions)

这遵循您引用的堆栈溢出答案,除了将端口提取到常量之外DefaultOptions::PORT。现在请注意,模块的名称没有什么神奇之处DefaultOptions,它只是定义了一个普通模块,然后添加到Rails::Server。您可以随意命名它。当开发服务器启动时,一个新的Rails::Server对象被实例化,并且在某个时刻default_options对该对象调用方法。由于使用prepend,方法查找将首先到达您定义的方法DefaultOptions. The super在该方法中只需调用原始的未前置的default_options定义于Rails::Server.

为什么“很难”获取这些值default_options是因为它是一个实例方法,这意味着您只能在实例上访问它Rails::Server类,并且我们通常不拥有服务器对象。你可以这样访问它:

# config/development.config
require 'rails/commands/server'
Rails::Server.new.default_options[:Port]

但我认为这是不必要的依赖和对象创建。名字Rails::Server也意味着我们可能只想拥有此类的一个对象,并且我不会实例化服务器对象只是为了获取它们的配置哈希。因此,将端口提取为一个可以保存的常量,无论您是否有对服务器对象的引用 -DefaultOptions::PORT- 在我看来更干净。

所以,现在我们已经掌握了DefaultOptions::PORT常量,您可以在邮件程序中使用它:

# config/development.rb
  config.action_mailer.smtp_settings = {
  :port => DefaultOptions::PORT,
  :address => '...',
  :user_name => '...',
  :password => '...',
  :domain => '...',
  :authentication => :plain
}

您还可以考虑将邮件程序和端口定义放在yaml文件,这样您就不需要将配置的各个部分“散布”在不同的位置 - 这可能会节省您以后的麻烦。

如果您想这样做,您可以自己创建一个包装类,使用YAML.load_file加载新的yaml配置文件转换成哈希值。或者,查看Figarogem,它提供了一种将所有 Rails 配置放置在单个文件中的便捷方法 -application.yml- 并使用以下方式从任何地方访问它们ENV.

如果你要使用Figaro,例如,并且有PORT key in application.yml,那么您的代码可能如下所示:

# config/boot.rb
require 'rails/commands/server'
module DefaultOptions
  def default_options
    super.merge!(Port: ENV['PORT'])
  end
end

Rails::Server.prepend(DefaultOptions)

# config/development.rb
config.action_mailer.smtp_settings = {
  :port => ENV['PORT'],
  :address => ENV['SMTP_SERVER'],
  :user_name => ENV['SMTP_LOGIN'],
  :password => ENV['SMTP_PASSWORD'],
  :domain => ENV['MAILER_DOMAIN'],
  :authentication => :plain
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ActionMailer 的 default_url_options:如何从 DefaultOptions 自动检索端口? 的相关文章

随机推荐