我经常并行运行许多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
设置它。这怎么可能?
答案 0 :(得分:1)
以下是与您的代码的小偏差:
# 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)
这是在您引用的Stack Overflow答案之后,但将端口提取到常量DefaultOptions::PORT
除外。现在请注意,模块DefaultOptions
的名称没有任何神奇之处,它只是定义了一个普通模块,然后将其添加到Rails::Server
之前。你可以根据需要命名它。启动开发服务器时,会实例化一个新的Rails::Server
对象,并且在某个时刻会在该对象上调用default_options
方法。由于使用prepend
,方法查找将首先到达您在DefaultOptions
中定义的方法。该方法中的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
配置文件加载到哈希中。或者,查看Figaro
gem,它提供了一种方便的方法将所有Rails配置放在一个文件中application.yml
- 并使用ENV
从任何地方访问它们。
例如,如果您使用Figaro
并在PORT
中使用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
}
答案 1 :(得分:0)
您可以使用Rails::Server::Options获取所需信息,然后相应地配置ActionMailer:
config.action_mailer.default_url_options = { host: Rails::Server.new.options[:Host], port: Rails::Server.new.options[:Port] }