class Rails::Application
application other than Rails.application, then you must run them manually.
If you decide to define rake tasks, runners, or initializers in an
the configuration.
on one of the applications to create a copy of the application which shares
to initialize the second application. You can also use the initialize_copy
In the above example, the configuration from the first application was used
second_application = Application.new(config: first_application.config)
first_application = Application.new
end
class Application < Rails::Application
that has already been created:
To create a new application, you can instantiate a new instance of a class
it with a different application.
that is initialized will be set to Rails.application, unless you override
If you decide to define multiple applications, then the first application
== Multiple Applications
11) Run config.after_initialize callbacks
10) Run config.before_eager_load and eager_load! if eager_load is true
9) Build the middleware stack and run to_prepare callbacks
8) Custom Railtie#initializers added by railties, engines and applications are executed
One by one, each engine sets up its load paths, routes and runs its config/initializers/* files.
7) Run Railtie#initializer defined by railties, engines and application.
6) Run config.before_initialize callbacks
5) Load config/environments/ENV.rb
4) Run config.before_configuration callbacks
3) Define Rails.application as “class MyApp::Application < Rails::Application”
2) require railties and engines
1) require “config/boot.rb” to setup load paths
the booting process goes like this:
process. From the moment you require “config/application.rb” in your app,
The application is also responsible for setting up and executing the booting
== Booting process
The Application is also responsible for building the middleware stack.
== Middlewares
whenever the files change in development.
The application object is also responsible for holding the routes and reloading routes
== Routes
Check Rails::Application::Configuration to see them all.
“logger” and so forth.
“cache_classes”, “consider_all_requests_local”, “filter_parameters”,
the application object has several specific configurations, for example
Besides providing the same configuration as Rails::Engine and Rails::Railtie,
== Configuration
are executed (check Rails::Application::Finisher).
Rails::Application::Bootstrap) and finishing initializers, after all the others
initializers. It also executes some bootstrap initializers (check
Rails::Application is responsible for executing all railties and engines
== Initialization
An Engine with the responsibility of coordinating the whole boot process.
def self.add_lib_to_load_path!(root) #:nodoc:
you need to load files in lib/ during the application configuration as well.
Rails application, you will need to add lib to $LOAD_PATH on your own in case
are changing config.root inside your application definition or having a custom
Notice this method takes into consideration the default root path. So if you
end
config.i18n.backend = MyBackend
require "my_backend" # in lib/my_backend
class MyApplication < Rails::Application
configuration.
allowing the developer to load classes in lib and use them during application
This method is called just after an application inherits from Rails::Application,
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
def build_middleware
def build_middleware config.app_middleware + super end
def build_request(env)
def build_request(env) req = super env["ORIGINAL_FULLPATH"] = req.fullpath env["ORIGINAL_SCRIPT_NAME"] = req.script_name req end
def config #:nodoc:
def config #:nodoc: @config ||= Application::Configuration.new(self.class.find_root(self.class.called_from)) end
def config=(configuration) #:nodoc:
def config=(configuration) #:nodoc: @config = configuration end
def config_for(name, env: Rails.env)
config.middleware.use ExceptionNotifier, config_for(:exception_notification)
Rails.application.configure do
# config/environments/production.rb
namespace: my_app_development
url: http://localhost:3001
development:
namespace: my_app_production
url: http://127.0.0.1:8080
production:
# config/exception_notification.yml:
Example:
Convenience for loading config/foo.yml for the current Rails env.
def config_for(name, env: Rails.env) if name.is_a?(Pathname) yaml = name else yaml = Pathname.new("#{paths["config"].existent.first}/#{name}.yml") end if yaml.exist? require "erb" (YAML.load(ERB.new(yaml.read).result) || {})[env] || {} else raise "Could not load configuration. No such file - #{yaml}" end rescue Psych::SyntaxError => e raise "YAML syntax error occurred while parsing #{yaml}. " \ "Please note that YAML must be consistently indented using spaces. Tabs are not allowed. " \ "Error: #{e.message}" end
def console(&blk)
Sends any console called in the instance of a new application up
def console(&blk) self.class.console(&blk) end
def create(initial_variable_values = {}, &block)
def create(initial_variable_values = {}, &block) new(initial_variable_values, &block).run_load_hooks! end
def default_middleware_stack #:nodoc:
def default_middleware_stack #:nodoc: default_stack = DefaultMiddlewareStack.new(self, config, paths) default_stack.build_stack end
def env_config
Stores some of the Rails initial environment parameters which
def env_config @app_env_config ||= begin validate_secret_key_config! super.merge( "action_dispatch.parameter_filter" => config.filter_parameters, "action_dispatch.redirect_filter" => config.filter_redirect, "action_dispatch.secret_token" => secrets.secret_token, "action_dispatch.secret_key_base" => secrets.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.cookies_serializer" => config.action_dispatch.cookies_serializer, "action_dispatch.cookies_digest" => config.action_dispatch.cookies_digest ) end end
def find_root(from)
def find_root(from) find_root_with_flag "config.ru", from, Dir.pwd end
def generators(&blk)
Sends any generators called in the instance of a new application up
def generators(&blk) self.class.generators(&blk) end
def helpers_paths #:nodoc:
def helpers_paths #:nodoc: config.helpers_paths end
def inherited(base)
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
def initialize(initial_variable_values = {}, &block)
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
def initialize!(group=:default) #:nodoc:
group is :default
Initialize the application passing the given group. By default, the
def initialize!(group=:default) #:nodoc: raise "Application has been already initialized." if @initialized run_initializers(group, self) @initialized = true self end
def initialized?
def initialized? @initialized end
def initializer(name, opts={}, &block)
Rails::Initializable module. Each Rails::Application class has its own
Sends the initializers to the +initializer+ method defined in the
def initializer(name, opts={}, &block) self.class.initializer(name, opts, &block) end
def initializers #:nodoc:
def initializers #:nodoc: Bootstrap.initializers_for(self) + railties_initializers(super) + Finisher.initializers_for(self) end
def instance
def instance super.run_load_hooks! end
def isolate_namespace(mod)
def isolate_namespace(mod) self.class.isolate_namespace(mod) end
def key_generator
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 ||= if secrets.secret_key_base unless secrets.secret_key_base.kind_of?(String) raise ArgumentError, "`secret_key_base` for #{Rails.env} environment must be a type of String, change this value in `config/secrets.yml`" end key_generator = ActiveSupport::KeyGenerator.new(secrets.secret_key_base, iterations: 1000) ActiveSupport::CachingKeyGenerator.new(key_generator) else ActiveSupport::LegacyKeyGenerator.new(secrets.secret_token) end end
def message_verifier(verifier_name)
# => 'my sensible data'
Rails.application.message_verifier('sensitive_data').verify(message)
message = Rails.application.message_verifier('sensitive_data').generate('my sensible data')
==== Examples
* +verifier_name+ - the name of the message verifier.
==== Parameters
verifiers passing the +verifier_name+ argument.
It is recommended not to use the same verifier for different things, so you can get different
This verifier can be used to generate and verify signed messages in the application.
Returns a message verifier object.
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
def migration_railties # :nodoc:
+railties_order+.
copying migrations from railties ; we need them in the order given by
While running initializers we need engines in reverse order here when
and the order specified by the +railties_order+ config.
Return an array of railties respecting the order they're loaded
def migration_railties # :nodoc: ordered_railties.flatten - [self] end
def ordered_railties #:nodoc:
Returns the ordered railties for this application considering railties_order.
def ordered_railties #:nodoc: @ordered_railties ||= begin order = config.railties_order.map do |railtie| if railtie == :main_app self elsif railtie.respond_to?(:instance) railtie.instance else railtie end end all = (railties - order) all.push(self) unless (all + order).include?(self) order.push(:all) unless order.include?(:all) index = order.index(:all) order[index] = all order end end
def railties_initializers(current) #:nodoc:
def railties_initializers(current) #:nodoc: initializers = [] ordered_railties.reverse.flatten.each do |r| if r == self initializers += current else initializers += r.initializers end end initializers end
def rake_tasks(&block)
If you try to define a set of rake tasks on the instance, these will get
def rake_tasks(&block) self.class.rake_tasks(&block) end
def reload_routes!
def reload_routes! routes_reloader.reload! end
def require_environment! #:nodoc:
def require_environment! #:nodoc: environment = paths["config/environment"].existent.first require environment if environment end
def routes_reloader #:nodoc:
def routes_reloader #:nodoc: @routes_reloader ||= RoutesReloader.new end
def run_console_blocks(app) #:nodoc:
def run_console_blocks(app) #:nodoc: railties.each { |r| r.run_console_blocks(app) } super end
def run_generators_blocks(app) #:nodoc:
def run_generators_blocks(app) #:nodoc: railties.each { |r| r.run_generators_blocks(app) } super end
def run_load_hooks! # :nodoc:
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
def run_runner_blocks(app) #:nodoc:
def run_runner_blocks(app) #:nodoc: railties.each { |r| r.run_runner_blocks(app) } super end
def run_tasks_blocks(app) #:nodoc:
def run_tasks_blocks(app) #:nodoc: railties.each { |r| r.run_tasks_blocks(app) } super require "rails/tasks" task :environment do ActiveSupport.on_load(:before_initialize) { config.eager_load = false } require_environment! end end
def runner(&blk)
Sends any runner called in the instance of a new application up
def runner(&blk) self.class.runner(&blk) end
def secrets
+Rails.application.secrets.namespace+ returns +my_app_production+ in the
namespace: my_app_production
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
production:
secret_key_base: 5a37811464e7d378488b0f073e2193b093682e4e21f5d6f3ae0a4e1781e61a351fdc878a843424e81c73fb484a40d23f92c8dafac4870e74ede6e5e174423010
test:
secret_key_base: 836fa3665997a860728bcb9e9a1e704d427cfc920e79d847d79c8a9a907b9e965defa4154b2b86bdec6930adbe33f21364523a6f6ce363865724549fdfc08553
development:
Example:
Returns secrets added to config/secrets.yml.
def secrets @secrets ||= begin secrets = ActiveSupport::OrderedOptions.new yaml = config.paths["config/secrets"].first if File.exist?(yaml) require "erb" all_secrets = YAML.load(ERB.new(IO.read(yaml)).result) || {} env_secrets = all_secrets[Rails.env] secrets.merge!(env_secrets.symbolize_keys) if env_secrets end # Fallback to config.secret_key_base if secrets.secret_key_base isn't set secrets.secret_key_base ||= config.secret_key_base # Fallback to config.secret_token if secrets.secret_token isn't set secrets.secret_token ||= config.secret_token secrets end end
def secrets=(secrets) #:nodoc:
def secrets=(secrets) #:nodoc: @secrets = secrets end
def to_app #:nodoc:
def to_app #:nodoc: self end
def validate_secret_key_config! #:nodoc:
def validate_secret_key_config! #:nodoc: if secrets.secret_key_base.blank? ActiveSupport::Deprecation.warn "You didn't set `secret_key_base`. " + "Read the upgrade documentation to learn more about this new config option." if secrets.secret_token.blank? raise "Missing `secret_key_base` for '#{Rails.env}' environment, set this value in `config/secrets.yml`" end end end
def watchable_args #:nodoc:
API.
directories-extensions suitable for ActiveSupport::FileUpdateChecker
Returns an array of file paths appended with a hash of
def watchable_args #:nodoc: files, dirs = config.watchable_files.dup, config.watchable_dirs.dup ActiveSupport::Dependencies.autoload_paths.each do |path| dirs[path.to_s] = [:rb] end [files, dirs] end