Spec-Zone.ru › Ruby on Rails 6.1

класс Rails::Application

Родитель:
Engine

Объект Engine с ответственностью за координацию всего процесса загрузки.

Инициализация

Rails::Application отвечает за выполнение инициализаторов всех railties и engines. Он также выполняет некоторые инициализаторы bootstrap (проверьте Rails::Application::Bootstrap) и завершающие инициализаторы, после выполнения всех остальных (проверьте Rails::Application::Finisher).

Configuration

Помимо предоставления той же конфигурации, что и Rails::Engine и Rails::Railtie, объект приложения имеет несколько специфических конфигураций, например, “cache_classes”, “consider_all_requests_local”, “filter_parameters”, “logger” и так далее.

Проверьте Rails::Application::Configuration, чтобы увидеть их все.

Маршруты

Объект приложения также отвечает за хранение маршрутов и их перезагрузку при изменении файлов в режиме разработки.

Средствами

Объект Application также отвечает за построение стека middleware.

Процесс загрузки

Приложение также отвечает за настройку и выполнение процесса загрузки. С момента запроса «config/application.rb» в вашем приложении процесс загрузки проходит так:

1)  require "config/boot.rb" to set up load paths
2)  require railties and engines
3)  Define Rails.application as "class MyApp::Application < Rails::Application"
4)  Run config.before_configuration callbacks
5)  Load config/environments/ENV.rb
6)  Run config.before_initialize callbacks
7)  Run Railtie#initializer defined by railties, engines and application.
    One by one, each engine sets up its load paths, routes and runs its config/initializers/* files.
8)  Custom Railtie#initializers added by railties, engines and applications are executed
9)  Build the middleware stack and run to_prepare callbacks
10) Run config.before_eager_load and eager_load! if eager_load is true
11) Run config.after_initialize callbacks

Несколько приложений

Если вы решите определить несколько приложений, то первое инициализированное приложение будет установлено как Rails.application, если вы не переопределите его другим приложением.

Чтобы создать новое приложение, вы можете создать новый экземпляр класса, который уже был создан:

class Application < Rails::Application
end

first_application  = Application.new
second_application = Application.new(config: first_application.config)

В приведенном выше примере конфигурация из первого приложения использовалась для инициализации второго приложения. Вы также можете использовать initialize_copy для одного из приложений, чтобы создать копию приложения, которая разделяет конфигурацию.

Если вы решите определить задачи Rake, исполнители или инициализаторы в приложении, отличном от Rails.application, то вы должны запустить их вручную.

Атрибуты

assets[RW]
config[W]
credentials[W]
executor[R]
reloader[R]
reloaders[R]
sandbox[RW]
sandbox?[RW]
secrets[W]

Общедоступные методы класса

create(initial_variable_values = {}, &block) Показать исходный код
# File railties/lib/rails/application.rb, line 103
def create(initial_variable_values = {}, &block)
  new(initial_variable_values, &block).run_load_hooks!
end
find_root(from) Показать исходный код
# File railties/lib/rails/application.rb, line 107
def find_root(from)
  find_root_with_flag "config.ru", from, Dir.pwd
end
inherited(base) Показать исходный код
# File railties/lib/rails/application.rb, line 92
def inherited(base)
  super
  Rails.app_class = base
  add_lib_to_load_path!(find_root(base.called_from))
  ActiveSupport.run_load_hooks(:before_configuration, base)
end
Вызывает метод суперкласса
instance() Показать исходный код
# File railties/lib/rails/application.rb, line 99
def instance
  super.run_load_hooks!
end
Вызывает метод суперкласса
new(initial_variable_values = {}, &block) Показать исходный код
# File railties/lib/rails/application.rb, line 128
def initialize(initial_variable_values = {}, &block)
  super()
  @initialized       = false
  @reloaders         = []
  @routes_reloader   = nil
  @app_env_config    = nil
  @ordered_railties  = nil
  @railties          = nil
  @message_verifiers = {}
  @ran_load_hooks    = false

  @executor          = Class.new(ActiveSupport::Executor)
  @reloader          = Class.new(ActiveSupport::Reloader)
  @reloader.executor = @executor

  # are these actually used?
  @initial_variable_values = initial_variable_values
  @block = block
end
Вызывает метод суперкласса

Публичные методы экземпляра

config_for(name, env: Rails.env) Показать исходный код
# File railties/lib/rails/application.rb, line 241
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 config.is_a?(Hash)
      ActiveSupport::OrderedOptions.new.update(shared&.deep_merge(config) || config)
    else
      config || shared
    end
  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

# You can also store configurations in a shared section which will be
# merged with the environment configuration

# 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 }
console(&blk) Показать исходный код
# File railties/lib/rails/application.rb, line 315
def console(&blk)
  self.class.console(&blk)
end

Отправляет любой вызов консоли в экземпляре нового приложения в метод console , определённый в Rails::Railtie.

credentials() Показать исходный код
# File railties/lib/rails/application.rb, line 443
def credentials
  @credentials ||= encrypted(config.credentials.content_path, key_path: config.credentials.key_path)
end

Расшифровывает хеш аутентификационных данных, хранящихся в config/credentials.yml.enc. Этот файл зашифрован с помощью Rails главного ключа, который берется либо из ENV["RAILS_MASTER_KEY"], либо из загруженного config/master.key. Если существует отдельный файл аутентификационных данных для текущей среды, он имеет приоритет. Таким образом, для среды production сначала ищется файл config/credentials/production.yml.enc, и главный ключ берется из ENV["RAILS_MASTER_KEY"] или загруженного config/credentials/production.key. Стандартное поведение можно переопределить, установив config.credentials.content_path и config.credentials.key_path.

eager_load!() Показать исходный код
# File railties/lib/rails/application.rb, line 508
def eager_load!
  if Rails.autoloaders.zeitwerk_enabled?
    Rails.autoloaders.each(&:eager_load)
  else
    super
  end
end

Загружает код приложения с ускорением.

Вызывает метод суперкласса
encrypted(path, key_path: "config/master.key", env_key: "RAILS_MASTER_KEY") Показать исходный код
# File railties/lib/rails/application.rb, line 474
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

Сокращение для расшифровки любых зашифрованных конфигураций или файлов.

Для любого файла, добавленного с помощью вызова rails encrypted:edit, используйте read, чтобы расшифровать файл с помощью главного ключа. Главный ключ хранится либо в config/master.key, либо в ENV["RAILS_MASTER_KEY"].

Rails.application.encrypted("config/mystery_man.txt.enc").read
# => "We've met before, haven't we?"

Также можно интерпретировать зашифрованные YAML-файлы с помощью config.

Rails.application.encrypted("config/credentials.yml.enc").config
# => { next_guys_line: "I don't think so. Where was it you think we met?" }

Любые конфигурации верхнего уровня также доступны напрямую в возвращаемом значении:

Rails.application.encrypted("config/credentials.yml.enc").next_guys_line
# => "I don't think so. Where was it you think we met?"

Файлы или конфигурации также могут быть зашифрованы с помощью пользовательского ключа. Для расшифровки с ключом в ENV, используйте:

Rails.application.encrypted("config/special_tokens.yml.enc", env_key: "SPECIAL_TOKENS")

Или для расшифровки с файлом, который следует игнорировать в системе управления версиями, относительно Rails.root:

Rails.application.encrypted("config/special_tokens.yml.enc", key_path: "config/special_tokens.key")
env_config() Показать исходный код
# File railties/lib/rails/application.rb, line 261
def env_config
  @app_env_config ||= begin
    super.merge(
      "action_dispatch.parameter_filter" => config.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.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
end

Хранит некоторые начальные параметры среды, которые будут использованы middleware и модулями для их настройки.

Вызывает метод суперкласса
generators(&blk) Показать исходный код
# File railties/lib/rails/application.rb, line 321
def generators(&blk)
  self.class.generators(&blk)
end

Отправляет любые вызовы генераторов в экземпляре нового приложения в метод generators , определённый в Rails::Railtie.

initialized?() Показать исходный код
# File railties/lib/rails/application.rb, line 149
def initialized?
  @initialized
end

Возвращает true, если приложение инициализировано.

initializer(name, opts = {}, &block) Показать исходный код
# File railties/lib/rails/application.rb, line 303
def initializer(name, opts = {}, &block)
  self.class.initializer(name, opts, &block)
end

Отправляет инициализаторы в метод initializer , определённый в модуле Rails::Initializable. Каждый класс Rails::Application имеет свой набор инициализаторов, определённых модулем Initializable.

isolate_namespace(mod) Показать исходный код
# File railties/lib/rails/application.rb, line 332
def isolate_namespace(mod)
  self.class.isolate_namespace(mod)
end

Отправляет метод isolate_namespace в метод класса.

key_generator() Показать исходный код
# File railties/lib/rails/application.rb, line 173
def key_generator
  # number of iterations selected based on consultation with the google security
  # team. Details at https://github.com/rails/rails/pull/6952#issuecomment-7661220
  @caching_key_generator ||= ActiveSupport::CachingKeyGenerator.new(
    ActiveSupport::KeyGenerator.new(secret_key_base, iterations: 1000)
  )
end

Возвращает генератор ключей приложения.

message_verifier(verifier_name) Показать исходный код
# File railties/lib/rails/application.rb, line 199
def message_verifier(verifier_name)
  @message_verifiers[verifier_name] ||= begin
    secret = key_generator.generate_key(verifier_name.to_s)
    ActiveSupport::MessageVerifier.new(secret)
  end
end

Возвращает объект верификатора сообщений.

Этот верификатор может использоваться для генерации и проверки подписанных сообщений в приложении.

Рекомендуется не использовать один и тот же верификатор для разных целей, поэтому можно получить разные верификаторы, передавая аргумент verifier_name.

Параметры

  • verifier_name - имя верификатора сообщений.

Примеры

message = Rails.application.message_verifier('sensitive_data').generate('my sensible data')
Rails.application.message_verifier('sensitive_data').verify(message)
# => 'my sensible data'

См. документацию по ActiveSupport::MessageVerifier для получения дополнительной информации.

rake_tasks(&block) Показать исходный код
# File railties/lib/rails/application.rb, line 296
def rake_tasks(&block)
  self.class.rake_tasks(&block)
end

Если вы пытаетесь определить набор задач Rake в экземпляре, они будут переданы в задачи Rake, определённые в классе приложения.

reload_routes!() Показать исходный код
# File railties/lib/rails/application.rb, line 168
def reload_routes!
  routes_reloader.reload!
end

Перезагрузить маршруты приложения независимо от того, изменились ли они.

runner(&blk) Показать исходный код
# File railties/lib/rails/application.rb, line 309
def runner(&blk)
  self.class.runner(&blk)
end

Отправляет любые вызовы runner в экземпляре нового приложения в метод runner , определённый в Rails::Railtie.

secret_key_base() Показать исходный код
# File railties/lib/rails/application.rb, line 426
def secret_key_base
  if Rails.env.development? || Rails.env.test?
    secrets.secret_key_base ||= generate_development_secret
  else
    validate_secret_key_base(
      ENV["SECRET_KEY_BASE"] || credentials.secret_key_base || secrets.secret_key_base
    )
  end
end

secret_key_base используется в качестве секретного ввода для генератора ключей приложения, который в свою очередь используется для создания всех MessageVerifiers/MessageEncryptors, включая те, которые подписывают и шифруют куки.

В средах разработки и тестирования он генерируется случайным образом и сохраняется во временном файле в tmp/development_secret.txt.

Во всех остальных средах мы сначала ищем его в ENV, затем в credentials.secret_key_base и, наконец, в secrets.secret_key_base. Для большинства приложений правильное место для его хранения — в зашифрованном файле аутентификационных данных.

secrets() Показать исходный код
# File railties/lib/rails/application.rb, line 401
def secrets
  @secrets ||= begin
    secrets = ActiveSupport::OrderedOptions.new
    files = config.paths["config/secrets"].existent
    files = files.reject { |path| path.end_with?(".enc") } unless config.read_encrypted_secrets
    secrets.merge! Rails::Secrets.parse(files, env: Rails.env)

    # Fallback to config.secret_key_base if secrets.secret_key_base isn't set
    secrets.secret_key_base ||= config.secret_key_base

    secrets
  end
end
server(&blk) Показать исходный код
# File railties/lib/rails/application.rb, line 327
def server(&blk)
  self.class.server(&blk)
end

Отправляет любые вызовы сервера в экземпляре нового приложения в метод server , определённый в Rails::Railtie.

Защищенные методы экземпляра

validate_secret_key_base(secret_key_base) Показать исходный код
# File railties/lib/rails/application.rb, line 590
def validate_secret_key_base(secret_key_base)
  if secret_key_base.is_a?(String) && secret_key_base.present?
    secret_key_base
  elsif secret_key_base
    raise ArgumentError, "`secret_key_base` for #{Rails.env} environment must be a type of String`"
  else
    raise ArgumentError, "Missing `secret_key_base` for '#{Rails.env}' environment, set this string with `bin/rails credentials:edit`"
  end
end

© 2004–2020 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API