跳至內文 跳至搜尋

具備負責協調整個開機程式的Engine

初始化

Rails::Application負責執行所有 Rails 和引擎的初始化器。它也會在執行其他初始化器後執行一些開機初始化器(請檢查Rails::Application::Bootstrap)和完成初始化器(請檢查Rails::Application::Finisher)。

組態

除了提供相同組態,例如 Rails::EngineRails::Railtie 之外,應用程式物件還有數個特定組態,例如 enable_reloadingconsider_all_requests_localfilter_parameterslogger 等。

請檢查Rails::Application::Configuration查看全部。

路由

應用程式物件也負責保留路由,並在開發期間檔案有異動時重新載入路由。

中間件

Application 也負責建立中間件堆疊。

開機處理

應用程式還負責設定並執行開機程序。從您在應用程式中需要 config/application.rb 的那一刻起,開機程序將按以下方式進行

  1. require "config/boot.rb" 以設定載入路徑。

  2. require Rails 和引擎。

  3. 定義 Rails.applicationclass MyApp::Application < Rails::Application

  4. 執行 config.before_configuration 回呼。

  5. 載入 config/environments/ENV.rb

  6. 執行 config.before_initialize 回呼。

  7. 執行由 Rails、引擎和應用程式定義的 Railtie#initializer。每個引擎會逐一設定其載入路徑和路由,並執行其 config/initializers/* 檔案。

  8. 執行由 Rails、引擎和應用程式新增的客製化 Railtie#initializers

  9. 建立中間件堆疊並執行 to_prepare 回呼。

  10. 如果 eager_loadtrue,則執行 config.before_eager_loadeager_load!

  11. 執行 config.after_initialize 回呼。

命名空間
方法
C
D
E
F
G
I
K
M
N
R
S

屬性

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

類別公用方法

create(initial_variable_values = {}, &block)

# File railties/lib/rails/application.rb, line 84
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 88
def find_root(from)
  find_root_with_flag "config.ru", from, Dir.pwd
end

inherited(base)

# File railties/lib/rails/application.rb, line 71
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

instance()

# File railties/lib/rails/application.rb, line 80
def instance
  super.run_load_hooks!
end

new(initial_variable_values = {}, &block)

# File railties/lib/rails/application.rb, line 109
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

實例公開方法

config_for(name, env: Rails.env)

載入目前 Rails 環境的 config/foo.yml 的便利功能。範例

# config/exception_notification.yml:
production:
  url: http://127.0.0.1:8080
  namespace: my_app_production

development:
  url: https://127.0.0.1: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 288
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

console(&blk)

將在新的應用程式實例中呼叫的任何主控台傳送至 Rails::Railtie 中定義的 console 方法。

# File railties/lib/rails/application.rb, line 371
def console(&blk)
  self.class.console(&blk)
end

credentials()

傳回 config.credentials.content_path 指定的認證檔的 ActiveSupport::EncryptedConfiguration 實例。

預設情況下,config.credentials.content_path 會指向目前環境的 config/credentials/#{environment}.yml.enc (例如,production 環境的 config/credentials/production.yml.enc),如果該檔案不存在,則會指向 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 492
def credentials
  @credentials ||= encrypted(config.credentials.content_path, key_path: config.credentials.key_path)
end

deprecators()

已管理的移除集合(ActiveSupport::Deprecation::Deprecators)。集合的設定方法會影響集合中的所有移除。此外,集合的 silence 方法會將集合中在指定區塊持續時間內的所有移除靜默化。

# File railties/lib/rails/application.rb, line 244
def deprecators
  @deprecators ||= ActiveSupport::Deprecation::Deprecators.new.tap do |deprecators|
    deprecators[:railties] = Rails.deprecator
  end
end

eager_load!()

急切加載應用程式程式碼。

# File railties/lib/rails/application.rb, line 550
def eager_load!
  Rails.autoloaders.each(&:eager_load)
end

encrypted(path, key_path: "config/master.key", env_key: "RAILS_MASTER_KEY")

傳回已加密檔案的 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 511
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

env_config()

儲存部分 Rails 初始環境參數,中介軟體和引擎將會使用這些參數來設定自己。

# File railties/lib/rails/application.rb, line 317
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

generators(&blk)

將任何在新應用程式實例中呼叫的產生器傳送到 Rails::Railtie 中定義的 generators 方法。

# File railties/lib/rails/application.rb, line 377
def generators(&blk)
  self.class.generators(&blk)
end

initialized?()

如果應用程式已初始化,則傳回 true。

# File railties/lib/rails/application.rb, line 134
def initialized?
  @initialized
end

initializer(name, opts = {}, &block)

將初始化傳送到 Rails::Initializable 模組中定義的 initializer 方法。每個 Rails::Application 類別都有其自己的初始化設定,如 Initializable 模組所定義。

# File railties/lib/rails/application.rb, line 359
def initializer(name, opts = {}, &block)
  self.class.initializer(name, opts, &block)
end

isolate_namespace(mod)

isolate_namespace 方法傳送到類別方法。

# File railties/lib/rails/application.rb, line 388
def isolate_namespace(mod)
  self.class.isolate_namespace(mod)
end

key_generator(secret_key_base = self.secret_key_base)

針對指定的 `secret_key_base`,傳回金鑰產生器 (ActiveSupport::CachingKeyGenerator)。傳回值已備忘,因此使用相同 `secret_key_base` 的其他呼叫將傳回相同金鑰產生器執行個體。

# File railties/lib/rails/application.rb, line 172
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

message_verifier(verifier_name)

傳回訊息驗證器物件。

可以使用此驗證器在應用程式中產生和驗證簽署過訊息。

建議不要在不同事物上使用相同驗證器,因此您可以透過傳遞 `verifier_name` 引數取得不同的驗證器。

舉例而言, `ActiveStorage::Blob.signed_id_verifier` 即是使用此功能所實作,這可以確保 ID 字串未遭竄改,並可安全地用於尋找器。

請參閱 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 236
def message_verifier(verifier_name)
  message_verifiers[verifier_name]
end

message_verifiers()

傳回訊息驗證器工廠 (ActiveSupport::MessageVerifiers)。此工廠可用作設定和建立訊息驗證器 (ActiveSupport::MessageVerifier) 的集中點,以供您的應用程式使用。

預設情況下,此工廠所建立的訊息驗證器會使用預設 ActiveSupport::MessageVerifier 選項來產生訊息。您可以透過結合 ActiveSupport::MessageVerifiers#clear_rotationsActiveSupport::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 208
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

name()

傳回與連字號分隔的應用程式名稱。

MyApp::Application.new.name => "my-app"
# File railties/lib/rails/application.rb, line 141
def name
  self.class.name.underscore.dasherize.delete_suffix("/application")
end

rake_tasks(&block)

如果您嘗試在執行個體上定義一組 Rake 任務,它們將會傳遞至在應用程式類別上所定義的 Rake 任務。

# File railties/lib/rails/application.rb, line 352
def rake_tasks(&block)
  self.class.rake_tasks(&block)
end

reload_routes!()

重新載入應用程式路由,無論它們是否已變更。

# File railties/lib/rails/application.rb, line 160
def reload_routes!
  routes_reloader.reload!
end

runner(&blk)

傳送任何新的應用程式實例中所呼叫的 runner 至 Rails::Railtie 中定義的 runner 方法。

# File railties/lib/rails/application.rb, line 365
def runner(&blk)
  self.class.runner(&blk)
end

secret_key_base()

secret_key_base 用於作為應用程式金鑰產生器的輸入密鑰,進而用於建立所有 ActiveSupport::MessageVerifierActiveSupport::MessageEncryptor 實例,包括用來簽署和加密 Cookie 的實例。

在開發和測試環境中,這個金鑰會隨機產生並儲存在 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 474
def secret_key_base
  config.secret_key_base
end

server(&blk)

傳送任何新的應用程式實例中所呼叫的伺服器至 Rails::Railtie 中定義的 server 方法。

# File railties/lib/rails/application.rb, line 383
def server(&blk)
  self.class.server(&blk)
end

受實例保護的方法

ensure_generator_templates_added()

# File railties/lib/rails/application.rb, line 628
def ensure_generator_templates_added
  configured_paths = config.generators.templates
  configured_paths.unshift(*(paths["lib/templates"].existent - configured_paths))
end