Class: Rails::Application

Inherits:
Engine show all
Defined in:
lib/rails/application.rb,
lib/rails/application/finisher.rb,
lib/rails/application/bootstrap.rb,
lib/rails/application/configuration.rb,
lib/rails/application/routes_reloader.rb,
lib/rails/application/default_middleware_stack.rb

Overview

An Engine with the responsibility of coordinating the whole boot process.

Initialization

Rails::Application is responsible for executing all railties and engines initializers. It also executes some bootstrap initializers (check Rails::Application::Bootstrap) and finishing initializers, after all the others are executed (check Rails::Application::Finisher).

Configuration

Besides providing the same configuration as Rails::Engine and Rails::Railtie, the application object has several specific configurations, for example enable_reloading, consider_all_requests_local, filter_parameters, logger, and so forth.

Check Rails::Application::Configuration to see them all.

Routes

The application object is also responsible for holding the routes and reloading routes whenever the files change in development.

Middlewares

The Application is also responsible for building the middleware stack.

Booting process

The application is also responsible for setting up and executing the booting process. From the moment you require config/application.rb in your app, the booting process goes like this:

  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 and 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.

Defined Under Namespace

Modules: Bootstrap, Finisher Classes: Configuration, DefaultMiddlewareStack, RoutesReloader

Constant Summary collapse

INITIAL_VARIABLES =
[:config, :railties, :routes_reloader, :reloaders,
:routes, :helpers, :app_env_config]

Constants inherited from Railtie

Railtie::ABSTRACT_RAILTIES

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Engine

#app, #call, endpoint, #endpoint, find, #helpers, isolate_namespace, #load_console, #load_runner, #load_seed, #load_server, #load_tasks, #railties, #routes, #routes?

Methods inherited from Railtie

<=>, abstract_railtie?, #configure, configure, console, generators, #inspect, railtie_name, #railtie_namespace, rake_tasks, runner, server, subclasses

Methods included from Initializable

included, #run_initializers

Constructor Details

#initialize(initial_variable_values = {}, &block) ⇒ Application

Returns a new instance of Application.



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File '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

Instance Attribute Details

#assetsObject

Returns the value of attribute assets.



100
101
102
# File 'lib/rails/application.rb', line 100

def assets
  @assets
end

#autoloadersObject (readonly)

Returns the value of attribute autoloaders.



102
103
104
# File 'lib/rails/application.rb', line 102

def autoloaders
  @autoloaders
end

#configObject

:nodoc:



451
452
453
# File 'lib/rails/application.rb', line 451

def config # :nodoc:
  @config ||= Application::Configuration.new(self.class.find_root(self.class.called_from))
end

#credentialsObject

Returns an ActiveSupport::EncryptedConfiguration instance for the credentials file specified by config.credentials.content_path.

By default, config.credentials.content_path will point to either config/credentials/#{environment}.yml.enc for the current environment (for example, config/credentials/production.yml.enc for the production environment), or config/credentials.yml.enc if that file does not exist.

The encryption key is taken from either ENV["RAILS_MASTER_KEY"], or from the file specified by config.credentials.key_path. By default, config.credentials.key_path will point to either config/credentials/#{environment}.key for the current environment, or config/master.key if that file does not exist.



492
493
494
# File 'lib/rails/application.rb', line 492

def credentials
  @credentials ||= encrypted(config.credentials.content_path, key_path: config.credentials.key_path)
end

#executorObject (readonly)

Returns the value of attribute executor.



102
103
104
# File 'lib/rails/application.rb', line 102

def executor
  @executor
end

#reloaderObject (readonly)

Returns the value of attribute reloader.



102
103
104
# File 'lib/rails/application.rb', line 102

def reloader
  @reloader
end

#reloadersObject (readonly)

Returns the value of attribute reloaders.



102
103
104
# File 'lib/rails/application.rb', line 102

def reloaders
  @reloaders
end

#sandboxObject Also known as: sandbox?

Returns the value of attribute sandbox.



100
101
102
# File 'lib/rails/application.rb', line 100

def sandbox
  @sandbox
end

Class Method Details

.add_lib_to_load_path!(root) ⇒ Object

This method is called just after an application inherits from Rails::Application, allowing the developer to load classes in lib and use them during application configuration.

class MyApplication < Rails::Application
  require "my_backend" # in lib/my_backend
  config.i18n.backend = MyBackend
end

Notice this method takes into consideration the default root path. So if you are changing config.root inside your application definition or having a custom Rails application, you will need to add lib to $LOAD_PATH on your own in case you need to load files in lib/ during the application configuration as well.



407
408
409
410
411
412
# File 'lib/rails/application.rb', line 407

def self.add_lib_to_load_path!(root) # :nodoc:
  path = File.join(root, "lib")
  if File.exist?(path) && !$LOAD_PATH.include?(path)
    $LOAD_PATH.unshift(path)
  end
end

.create(initial_variable_values = {}, &block) ⇒ Object



84
85
86
# File 'lib/rails/application.rb', line 84

def create(initial_variable_values = {}, &block)
  new(initial_variable_values, &block).run_load_hooks!
end

.find_root(from) ⇒ Object



88
89
90
# File 'lib/rails/application.rb', line 88

def find_root(from)
  find_root_with_flag "config.ru", from, Dir.pwd
end

.inherited(base) ⇒ Object



71
72
73
74
75
76
77
78
# File '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

.instanceObject



80
81
82
# File 'lib/rails/application.rb', line 80

def instance
  super.run_load_hooks!
end

Instance Method Details

#config_for(name, env: Rails.env) ⇒ Object

Convenience for loading config/foo.yml for the current Rails env. Example:

# 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 }


288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
# File '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) ⇒ Object

Sends any console called in the instance of a new application up to the console method defined in Rails::Railtie.



371
372
373
# File 'lib/rails/application.rb', line 371

def console(&blk)
  self.class.console(&blk)
end

#deprecatorsObject

A managed collection of deprecators (ActiveSupport::Deprecation::Deprecators). The collection’s configuration methods affect all deprecators in the collection. Additionally, the collection’s silence method silences all deprecators in the collection for the duration of a given block.



244
245
246
247
248
# File 'lib/rails/application.rb', line 244

def deprecators
  @deprecators ||= ActiveSupport::Deprecation::Deprecators.new.tap do |deprecators|
    deprecators[:railties] = Rails.deprecator
  end
end

#eager_load!Object

Eager loads the application code.



550
551
552
# File '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") ⇒ Object

Returns an ActiveSupport::EncryptedConfiguration instance for an encrypted file. By default, the encryption key is taken from either ENV["RAILS_MASTER_KEY"], or from the config/master.key file.

my_config = Rails.application.encrypted("config/my_config.enc")

my_config.read
# => "foo:\n  bar: 123\n"

my_config.foo.bar
# => 123

Encrypted files can be edited with the bin/rails encrypted:edit command. (See the output of bin/rails encrypted:edit --help for more information.)



511
512
513
514
515
516
517
518
# File '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_configObject

Stores some of the Rails initial environment parameters which will be used by middlewares and engines to configure themselves.



317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
# File '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.,
      "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) ⇒ Object

Sends any generators called in the instance of a new application up to the generators method defined in Rails::Railtie.



377
378
379
# File 'lib/rails/application.rb', line 377

def generators(&blk)
  self.class.generators(&blk)
end

#helpers_pathsObject

:nodoc:



524
525
526
# File 'lib/rails/application.rb', line 524

def helpers_paths # :nodoc:
  config.helpers_paths
end

#initialize!(group = :default) ⇒ Object

Initialize the application passing the given group. By default, the group is :default



438
439
440
441
442
443
# File 'lib/rails/application.rb', line 438

def initialize!(group = :default) # :nodoc:
  raise "Application has been already initialized." if @initialized
  run_initializers(group, self)
  @initialized = true
  self
end

#initialized?Boolean

Returns true if the application is initialized.

Returns:

  • (Boolean)


134
135
136
# File 'lib/rails/application.rb', line 134

def initialized?
  @initialized
end

#initializer(name, opts = {}, &block) ⇒ Object

Sends the initializers to the initializer method defined in the Rails::Initializable module. Each Rails::Application class has its own set of initializers, as defined by the Initializable module.



359
360
361
# File 'lib/rails/application.rb', line 359

def initializer(name, opts = {}, &block)
  self.class.initializer(name, opts, &block)
end

#initializersObject

:nodoc:



445
446
447
448
449
# File 'lib/rails/application.rb', line 445

def initializers # :nodoc:
  Bootstrap.initializers_for(self) +
  railties_initializers(super) +
  Finisher.initializers_for(self)
end

#isolate_namespace(mod) ⇒ Object

Sends the isolate_namespace method up to the class method.



388
389
390
# File '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) ⇒ Object

Returns a key generator (ActiveSupport::CachingKeyGenerator) for a specified secret_key_base. The return value is memoized, so additional calls with the same secret_key_base will return the same key generator instance.



172
173
174
175
176
177
178
# File '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

#load_generators(app = self) ⇒ Object

:nodoc:



544
545
546
547
# File 'lib/rails/application.rb', line 544

def load_generators(app = self) # :nodoc:
  app.ensure_generator_templates_added
  super
end

#message_verifier(verifier_name) ⇒ Object

Returns a message verifier object.

This verifier can be used to generate and verify signed messages in the application.

It is recommended not to use the same verifier for different things, so you can get different verifiers passing the verifier_name argument.

For instance, ActiveStorage::Blob.signed_id_verifier is implemented using this feature, which assures that the IDs strings haven’t been tampered with and are safe to use in a finder.

See the ActiveSupport::MessageVerifier documentation for more information.

Parameters

  • verifier_name - the name of the message verifier.

Examples

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'


236
237
238
# File 'lib/rails/application.rb', line 236

def message_verifier(verifier_name)
  message_verifiers[verifier_name]
end

#message_verifiersObject

Returns a message verifier factory (ActiveSupport::MessageVerifiers). This factory can be used as a central point to configure and create message verifiers (ActiveSupport::MessageVerifier) for your application.

By default, message verifiers created by this factory will generate messages using the default ActiveSupport::MessageVerifier options. You can override these options with a combination of ActiveSupport::MessageVerifiers#clear_rotations and ActiveSupport::MessageVerifiers#rotate. However, this must be done prior to building any message verifier instances. For example, in a before_initialize block:

# 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

Message verifiers created by this factory will always use a secret derived from #secret_key_base when generating messages. clear_rotations will not affect this behavior. However, older secret_key_base values can be rotated for verifying messages:

# 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


208
209
210
211
212
213
# File '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

#migration_railtiesObject

Return an array of railties respecting the order they’re loaded and the order specified by the railties_order config.

While running initializers we need engines in reverse order here when copying migrations from railties ; we need them in the order given by railties_order.



540
541
542
# File 'lib/rails/application.rb', line 540

def migration_railties # :nodoc:
  ordered_railties.flatten - [self]
end

#nameObject

Returns the dasherized application name.

MyApp::Application.new.name => "my-app"


141
142
143
# File 'lib/rails/application.rb', line 141

def name
  self.class.name.underscore.dasherize.delete_suffix("/application")
end

#rake_tasks(&block) ⇒ Object

If you try to define a set of Rake tasks on the instance, these will get passed up to the Rake tasks defined on the application’s class.



352
353
354
# File 'lib/rails/application.rb', line 352

def rake_tasks(&block)
  self.class.rake_tasks(&block)
end

#reload_routes!Object

Reload application routes regardless if they changed or not.



160
161
162
# File 'lib/rails/application.rb', line 160

def reload_routes!
  routes_reloader.reload!
end

#reload_routes_unless_loadedObject

:nodoc:



164
165
166
# File 'lib/rails/application.rb', line 164

def reload_routes_unless_loaded # :nodoc:
  initialized? && routes_reloader.execute_unless_loaded
end

#require_environment!Object

:nodoc:



414
415
416
417
# File 'lib/rails/application.rb', line 414

def require_environment! # :nodoc:
  environment = paths["config/environment"].existent.first
  require environment if environment
end

#routes_reloaderObject

:nodoc:



419
420
421
# File 'lib/rails/application.rb', line 419

def routes_reloader # :nodoc:
  @routes_reloader ||= RoutesReloader.new
end

#run_load_hooks!Object

:nodoc:



145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/rails/application.rb', line 145

def run_load_hooks! # :nodoc:
  return self if @ran_load_hooks
  @ran_load_hooks = true

  @initial_variable_values.each do |variable_name, value|
    if INITIAL_VARIABLES.include?(variable_name)
      instance_variable_set("@#{variable_name}", value)
    end
  end

  instance_eval(&@block) if @block
  self
end

#runner(&blk) ⇒ Object

Sends any runner called in the instance of a new application up to the runner method defined in Rails::Railtie.



365
366
367
# File 'lib/rails/application.rb', line 365

def runner(&blk)
  self.class.runner(&blk)
end

#secret_key_baseObject

The secret_key_base is used as the input secret to the application’s key generator, which in turn is used to create all ActiveSupport::MessageVerifier and ActiveSupport::MessageEncryptor instances, including the ones that sign and encrypt cookies.

In development and test, this is randomly generated and stored in a temporary file in tmp/local_secret.txt.

You can also set ENV["SECRET_KEY_BASE_DUMMY"] to trigger the use of a randomly generated secret_key_base that’s stored in a temporary file. This is useful when precompiling assets for production as part of a build step that otherwise does not need access to the production secrets.

Dockerfile example: RUN SECRET_KEY_BASE_DUMMY=1 bundle exec rails assets:precompile.

In all other environments, we look for it first in ENV["SECRET_KEY_BASE"], then credentials.secret_key_base. For most applications, the correct place to store it is in the encrypted credentials file.



474
475
476
# File 'lib/rails/application.rb', line 474

def secret_key_base
  config.secret_key_base
end

#server(&blk) ⇒ Object

Sends any server called in the instance of a new application up to the server method defined in Rails::Railtie.



383
384
385
# File 'lib/rails/application.rb', line 383

def server(&blk)
  self.class.server(&blk)
end

#to_appObject

:nodoc:



520
521
522
# File 'lib/rails/application.rb', line 520

def to_app # :nodoc:
  self
end

#watchable_argsObject

Returns an array of file paths appended with a hash of directories-extensions suitable for ActiveSupport::FileUpdateChecker API.



426
427
428
429
430
431
432
433
434
# File 'lib/rails/application.rb', line 426

def watchable_args # :nodoc:
  files, dirs = config.watchable_files.dup, config.watchable_dirs.dup

  Rails.autoloaders.main.dirs.each do |path|
    dirs[path] = [:rb]
  end

  [files, dirs]
end