класс Rails::Application
Объект Engine ответственный за координацию всего процесса запуска.
Инициализация
Rails::Application отвечает за выполнение всех инициализаторов railties и engines. Также он выполняет некоторые инициализаторы bootstrap (см. Rails::Application::Bootstrap) и завершающие инициализаторы, после того, как будут выполнены все остальные (см. Rails::Application::Finisher).
Настройка
Помимо предоставления той же настройки, что и Rails::Engine и Rails::Railtie, объект приложения имеет несколько специфичных настроек, например enable_reloading, consider_all_requests_local, filter_parameters, logger, и так далее.
Посмотреть их все можно в Rails::Application::Configuration.
Маршруты
Объект приложения также отвечает за хранение маршрутов и перезагрузку маршрутов всякий раз, когда файлы изменяются в режиме разработки.
Средства промежуточного слоя
Application также отвечает за построение стека middleware.
Процесс запуска
Приложение также отвечает за настройку и выполнение процесса запуска. С момента, когда вы требуете config/application.rb в своем приложении, процесс запуска происходит так:
-
require "config/boot.rb"для настройки путей загрузки. -
requirerailties и engines. -
Определить
Rails.applicationкакclass MyApp::Application < Rails::Application. -
Выполнить
config.before_configurationколбэки. -
Загрузить
config/environments/ENV.rb. -
Выполнить
config.before_initializeколбэки. -
Выполнить
Railtie#initializerопределенные railties, engines и приложением. По одному, каждый engine настраивает свои пути загрузки и маршруты, и выполняет своиconfig/initializers/*файлы. -
Выполняются пользовательские
Railtie#initializersдобавленные railties, engines и приложениями. -
Построить стек middleware и выполнить
to_prepareколбэки. -
Выполнить
config.before_eager_loadиeager_load!еслиeager_loadравноtrue. -
Выполнить
config.after_initializeколбэки.
Атрибуты
Публичные методы класса
# File railties/lib/rails/application.rb, line 83
def create(initial_variable_values = {}, &block)
new(initial_variable_values, &block).run_load_hooks!
end # File railties/lib/rails/application.rb, line 87 def find_root(from) find_root_with_flag "config.ru", from, Dir.pwd end
# File railties/lib/rails/application.rb, line 70 def inherited(base) super Rails.app_class = base # lib has to be added to $LOAD_PATH unconditionally, even if it's in the # autoload paths and config.add_autoload_paths_to_load_path is false. add_lib_to_load_path!(find_root(base.called_from)) ActiveSupport.run_load_hooks(:before_configuration, base) end
# File railties/lib/rails/application.rb, line 79 def instance super.run_load_hooks! end
# File railties/lib/rails/application.rb, line 108
def initialize(initial_variable_values = {}, &block)
super()
@initialized = false
@reloaders = []
@routes_reloader = nil
@app_env_config = nil
@ordered_railties = nil
@railties = nil
@key_generators = {}
@message_verifiers = nil
@deprecators = nil
@ran_load_hooks = false
@executor = Class.new(ActiveSupport::Executor)
@reloader = Class.new(ActiveSupport::Reloader)
@reloader.executor = @executor
@autoloaders = Rails::Autoloaders.new
# are these actually used?
@initial_variable_values = initial_variable_values
@block = block
end Публичные методы экземпляра
# File railties/lib/rails/application.rb, line 283
def config_for(name, env: Rails.env)
yaml = name.is_a?(Pathname) ? name : Pathname.new("#{paths["config"].existent.first}/#{name}.yml")
if yaml.exist?
require "erb"
all_configs = ActiveSupport::ConfigurationFile.parse(yaml).deep_symbolize_keys
config, shared = all_configs[env.to_sym], all_configs[:shared]
if shared
config = {} if config.nil? && shared.is_a?(Hash)
if config.is_a?(Hash) && shared.is_a?(Hash)
config = shared.deep_merge(config)
elsif config.nil?
config = shared
end
end
if config.is_a?(Hash)
config = ActiveSupport::OrderedOptions.new.update(config)
end
config
else
raise "Could not load configuration. No such file - #{yaml}"
end
end Удобный способ загрузки config/foo.yml для текущей среды Rails. Пример:
# config/exception_notification.yml: production: url: http://127.0.0.1:8080 namespace: my_app_production development: url: http://localhost:3001 namespace: my_app_development
# config/environments/production.rb Rails.application.configure do config.middleware.use ExceptionNotifier, config_for(:exception_notification) end
Вы также можете хранить конфигурации в общем разделе, который будет объединен с конфигурацией среды
# config/example.yml
shared:
foo:
bar:
baz: 1
development:
foo:
bar:
qux: 2 # development environment
Rails.application.config_for(:example)[:foo][:bar]
# => { baz: 1, qux: 2 }
# File railties/lib/rails/application.rb, line 366 def console(&blk) self.class.console(&blk) end
Отправляет любой вызов консоли в экземпляре нового приложения к методу console определенному в Rails::Railtie.
# File railties/lib/rails/application.rb, line 487 def credentials @credentials ||= encrypted(config.credentials.content_path, key_path: config.credentials.key_path) end
Возвращает экземпляр ActiveSupport::EncryptedConfiguration для файла учетных данных, указанного config.credentials.content_path.
По умолчанию, config.credentials.content_path будет указывать либо на config/credentials/#{environment}.yml.enc для текущей среды (например, config/credentials/production.yml.enc для среды production), либо на config/credentials.yml.enc, если этот файл не существует.
Ключ шифрования берется либо из ENV["RAILS_MASTER_KEY"], либо из файла, указанного config.credentials.key_path. По умолчанию, config.credentials.key_path будет указывать либо на config/credentials/#{environment}.key для текущей среды, либо на config/master.key, если этот файл не существует.
# File railties/lib/rails/application.rb, line 239
def deprecators
@deprecators ||= ActiveSupport::Deprecation::Deprecators.new.tap do |deprecators|
deprecators[:railties] = Rails.deprecator
end
end Управляемая коллекция устаревших методов (ActiveSupport::Deprecation::Deprecators). Методы конфигурации коллекции влияют на все устаревшие методы в коллекции. Кроме того, метод silence коллекции подавляет все устаревшие методы в коллекции на время выполнения данного блока.
# File railties/lib/rails/application.rb, line 545 def eager_load! Rails.autoloaders.each(&:eager_load) end
Предварительно загружает код приложения.
# File railties/lib/rails/application.rb, line 506
def encrypted(path, key_path: "config/master.key", env_key: "RAILS_MASTER_KEY")
ActiveSupport::EncryptedConfiguration.new(
config_path: Rails.root.join(path),
key_path: Rails.root.join(key_path),
env_key: env_key,
raise_if_missing_key: config.require_master_key
)
end Возвращает экземпляр ActiveSupport::EncryptedConfiguration для зашифрованного файла. По умолчанию ключ шифрования берется либо из ENV["RAILS_MASTER_KEY"], либо из файла config/master.key.
my_config = Rails.application.encrypted("config/my_config.enc")
my_config.read
# => "foo:\n bar: 123\n"
my_config.foo.bar
# => 123
Зашифрованные файлы можно редактировать с помощью команды bin/rails encrypted:edit. (См. вывод bin/rails encrypted:edit --help для получения дополнительной информации.)
# File railties/lib/rails/application.rb, line 312
def env_config
@app_env_config ||= super.merge(
"action_dispatch.parameter_filter" => filter_parameters,
"action_dispatch.redirect_filter" => config.filter_redirect,
"action_dispatch.secret_key_base" => secret_key_base,
"action_dispatch.show_exceptions" => config.action_dispatch.show_exceptions,
"action_dispatch.show_detailed_exceptions" => config.consider_all_requests_local,
"action_dispatch.log_rescued_responses" => config.action_dispatch.log_rescued_responses,
"action_dispatch.debug_exception_log_level" => ActiveSupport::Logger.const_get(config.action_dispatch.debug_exception_log_level.to_s.upcase),
"action_dispatch.logger" => Rails.logger,
"action_dispatch.backtrace_cleaner" => Rails.backtrace_cleaner,
"action_dispatch.key_generator" => key_generator,
"action_dispatch.http_auth_salt" => config.action_dispatch.http_auth_salt,
"action_dispatch.signed_cookie_salt" => config.action_dispatch.signed_cookie_salt,
"action_dispatch.encrypted_cookie_salt" => config.action_dispatch.encrypted_cookie_salt,
"action_dispatch.encrypted_signed_cookie_salt" => config.action_dispatch.encrypted_signed_cookie_salt,
"action_dispatch.authenticated_encrypted_cookie_salt" => config.action_dispatch.authenticated_encrypted_cookie_salt,
"action_dispatch.use_authenticated_cookie_encryption" => config.action_dispatch.use_authenticated_cookie_encryption,
"action_dispatch.encrypted_cookie_cipher" => config.action_dispatch.encrypted_cookie_cipher,
"action_dispatch.signed_cookie_digest" => config.action_dispatch.signed_cookie_digest,
"action_dispatch.cookies_serializer" => config.action_dispatch.cookies_serializer,
"action_dispatch.cookies_digest" => config.action_dispatch.cookies_digest,
"action_dispatch.cookies_rotations" => config.action_dispatch.cookies_rotations,
"action_dispatch.cookies_same_site_protection" => coerce_same_site_protection(config.action_dispatch.cookies_same_site_protection),
"action_dispatch.use_cookies_with_metadata" => config.action_dispatch.use_cookies_with_metadata,
"action_dispatch.content_security_policy" => config.content_security_policy,
"action_dispatch.content_security_policy_report_only" => config.content_security_policy_report_only,
"action_dispatch.content_security_policy_nonce_generator" => config.content_security_policy_nonce_generator,
"action_dispatch.content_security_policy_nonce_directives" => config.content_security_policy_nonce_directives,
"action_dispatch.permissions_policy" => config.permissions_policy,
)
end Хранит некоторые из начальных параметров среды Rails, которые будут использоваться промежуточным ПО и модулями для их собственной конфигурации.
# File railties/lib/rails/application.rb, line 372 def generators(&blk) self.class.generators(&blk) end
Отправляет любые генераторы, вызванные в экземпляре нового приложения, к методу generators определенному в Rails::Railtie.
# File railties/lib/rails/application.rb, line 133 def initialized? @initialized end
Возвращает true, если приложение инициализировано.
# File railties/lib/rails/application.rb, line 354
def initializer(name, opts = {}, &block)
self.class.initializer(name, opts, &block)
end Отправляет инициализаторы методу initializer определенному в модуле Rails::Initializable. Каждый класс Rails::Application имеет свой собственный набор инициализаторов, как определено модулем Initializable.
# File railties/lib/rails/application.rb, line 383 def isolate_namespace(mod) self.class.isolate_namespace(mod) end
Отправляет метод isolate_namespace к методу класса.
# File railties/lib/rails/application.rb, line 167
def key_generator(secret_key_base = self.secret_key_base)
# number of iterations selected based on consultation with the google security
# team. Details at https://github.com/rails/rails/pull/6952#issuecomment-7661220
@key_generators[secret_key_base] ||= ActiveSupport::CachingKeyGenerator.new(
ActiveSupport::KeyGenerator.new(secret_key_base, iterations: 1000)
)
end Возвращает генератор ключей (ActiveSupport::CachingKeyGenerator) для указанного secret_key_base. Возвращаемое значение кэшируется, поэтому дополнительные вызовы с тем же secret_key_base вернут тот же экземпляр генератора ключей.
# File railties/lib/rails/application.rb, line 231 def message_verifier(verifier_name) message_verifiers[verifier_name] end
Возвращает объект проверки сообщения.
Этот верификатор может использоваться для генерации и проверки подписанных сообщений в приложении.
Рекомендуется не использовать один и тот же верификатор для разных целей, поэтому вы можете получать разные верификаторы, передавая аргумент verifier_name.
Например, ActiveStorage::Blob.signed_id_verifier реализован с использованием этой функции, которая гарантирует, что строки идентификаторов не были изменены и безопасны для использования в средстве поиска.
См. документацию ActiveSupport::MessageVerifier для получения дополнительной информации.
Параметры
-
verifier_name- имя верификатора сообщения.
Примеры
message = Rails.application.message_verifier('my_purpose').generate('data to sign against tampering')
Rails.application.message_verifier('my_purpose').verify(message)
# => 'data to sign against tampering'
# File railties/lib/rails/application.rb, line 203
def message_verifiers
@message_verifiers ||=
ActiveSupport::MessageVerifiers.new do |salt, secret_key_base: self.secret_key_base|
key_generator(secret_key_base).generate_key(salt)
end.rotate_defaults
end Возвращает фабрику верификаторов сообщений (ActiveSupport::MessageVerifiers). Эта фабрика может использоваться в качестве центральной точки для настройки и создания верификаторов сообщений (ActiveSupport::MessageVerifier) для вашего приложения.
По умолчанию, верификаторы сообщений, созданные этой фабрикой, будут генерировать сообщения с использованием параметров ActiveSupport::MessageVerifier по умолчанию. Вы можете переопределить эти параметры с помощью комбинации ActiveSupport::MessageVerifiers#clear_rotations и ActiveSupport::MessageVerifiers#rotate. Однако это должно быть сделано до создания любых экземпляров верификаторов сообщений. Например, в блоке before_initialize:
# Use `url_safe: true` when generating messages config.before_initialize do |app| app.message_verifiers.clear_rotations app.message_verifiers.rotate(url_safe: true) end
Верификаторы сообщений, созданные этой фабрикой, всегда будут использовать секретный ключ, полученный из secret_key_base при генерации сообщений. clear_rotations не повлияет на это поведение. Однако старые значения secret_key_base могут быть повернуты для проверки сообщений:
# Fall back to old `secret_key_base` when verifying messages config.before_initialize do |app| app.message_verifiers.rotate(secret_key_base: "old secret_key_base") end
# File railties/lib/rails/application.rb, line 140
def name
self.class.name.underscore.dasherize.delete_suffix("/application")
end Возвращает название приложения с дефисами.
MyApp::Application.new.name => "my-app"
# File railties/lib/rails/application.rb, line 347 def rake_tasks(&block) self.class.rake_tasks(&block) end
Если вы пытаетесь определить набор задач Rake в экземпляре, они будут переданы задачам Rake, определённым в классе приложения.
# File railties/lib/rails/application.rb, line 159 def reload_routes! routes_reloader.reload! end
Перезагрузить маршруты приложения независимо от того, изменились они или нет.
# File railties/lib/rails/application.rb, line 360 def runner(&blk) self.class.runner(&blk) end
Отправляет любой вызов runner в экземпляре нового приложения методу runner , определённому в Rails::Railtie.
# File railties/lib/rails/application.rb, line 469 def secret_key_base config.secret_key_base end
secret_key_base используется в качестве секретного ввода для генератора ключей приложения, который, в свою очередь, используется для создания всех экземпляров ActiveSupport::MessageVerifier и ActiveSupport::MessageEncryptor, включая те, которые подписывают и шифруют куки.
В режиме разработки и тестирования он генерируется случайным образом и сохраняется во временном файле в tmp/local_secret.txt.
Вы также можете установить ENV["SECRET_KEY_BASE_DUMMY"], чтобы использовать случайно сгенерированный secret_key_base, хранящийся во временном файле. Это полезно при предварительной компиляции активов для производства в рамках шага сборки, который в противном случае не нуждается в доступе к секретам производства.
Пример Dockerfile: RUN SECRET_KEY_BASE_DUMMY=1 bundle exec rails assets:precompile.
Во всех остальных средах мы сначала ищем его в ENV["SECRET_KEY_BASE"], а затем в credentials.secret_key_base. Для большинства приложений правильное место для его хранения — в зашифрованном файле учетных данных.
# File railties/lib/rails/application.rb, line 378 def server(&blk) self.class.server(&blk) end
Отправляет любой вызов сервера в экземпляре нового приложения методу server , определённому в Rails::Railtie.
Защищенные методы экземпляра
# File railties/lib/rails/application.rb, line 623 def ensure_generator_templates_added configured_paths = config.generators.templates configured_paths.unshift(*(paths["lib/templates"].existent - configured_paths)) end
© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.