Oto małe odchylenie od kodu:
# 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)
Wynika to przepełnienie stosu odpowie pan zacytował, z wyjątkiem wydobywania port do stałej DefaultOptions::PORT
. Teraz zauważ, że nie ma nic magicznego w nazwie modułu DefaultOptions
, po prostu definiuje zwykły moduł, który jest następnie dodawany do Rails::Server
. Mogłeś nazwać go tak, jak chciałeś. Po uruchomieniu serwera programistycznego tworzony jest nowy obiekt Rails::Server
iw pewnym momencie wywoływana jest metoda default_options
dla tego obiektu. Z powodu użycia prepend
, wyszukiwanie metody osiągnie najpierw metodę określoną w DefaultOptions
. super
w tej metodzie po prostu wywołuje oryginalny nieprzypisany default_options
zdefiniowany w Rails::Server
.
Powodem, dla którego "trudno" uzyskać wartości w default_options
jest to, że jest to metoda instancji, co oznacza, że można uzyskać do niej dostęp tylko w instancji klasy Rails::Server
, a my zazwyczaj nie posiadamy blokady obiekt serwera. Można uzyskać do niego dostęp w następujący sposób:
# config/development.config
require 'rails/commands/server'
Rails::Server.new.default_options[:Port]
Ale myślę, że to niepotrzebne uzależnienie i tworzenie obiektu. Nazwa Rails::Server
oznacza również, że możemy chcieć mieć tylko jeden obiekt tej klasy, a ja nie tworzyłbym instancji obiektów serwera tylko po to, aby uzyskać ich skrót konfiguracji. W związku z tym wyodrębnianie portu do stałej, bez względu na to, czy masz odwołanie do obiektu serwera - DefaultOptions::PORT
- jest czystsze w moim umyśle.
Więc teraz, że mamy trzymać DefaultOptions::PORT
stałej, można używać go w mailer:
# config/development.rb
config.action_mailer.smtp_settings = {
:port => DefaultOptions::PORT,
:address => '...',
:user_name => '...',
:password => '...',
:domain => '...',
:authentication => :plain
}
Można również rozważyć Mailer'a i portu definicji w pliku yaml
, więc co robisz nie trzeba "posypywać" częściami swojej konfiguracji w różnych lokalizacjach - może to zaoszczędzić ci później.
Jeśli chcesz to zrobić, możesz utworzyć klasę opakowania samodzielnie, która używa YAML.load_file
, aby załadować nowy plik konfiguracyjny yaml
do wartości mieszania. Alternatywnie, sprawdź gem Figaro
, daje wygodny sposób na umieszczenie wszystkich konfiguracji Rails w jednym pliku - application.yml
- i dostęp do nich z dowolnego miejsca przy użyciu ENV
.
Jeśli było użyć Figaro
, na przykład, mają klucz application.yml
PORT
, wówczas kod może wyglądać następująco:
# 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
}