Ответ 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 Qaru 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
. super
в этом методе просто вызывает исходный un-prepended 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
}