Excerpt
Initializers are an important concept in Rails, but I couldn't find much information about them online, other than the official Rails guides. So on the weekend, I did a deep dive into the Rails initialization process, and what follows is everything I learned about initializers.
## What we'll learn:
By the end of the article, I hope you'll have a much better understanding of initializers and an appreciation of all the things that Rails does behind the scenes to not only make it work, but also make it look like magic!
Let's begin...
## What are Initializers?
An initializer is simply a piece of Ruby code under the config/initializers directory that you can use to configure your Rails application or external gems.
To create a new initializer, add a Ruby file in the config/initializers directory. Rails will run the initializers after loading the framework and any other gems used in your application.

Rails Initialization Sequence
As an example, consider the filter_parameter_logging initializer that Rails provides out-of-box. You can use it to hide sensitive data from the log file. This prevents sensitive data such as credit card numbers or auth keys from accidentally leaking into the log files.
```plain text
# config/initializers/filter_parameter_logging.rb
Rails.application.config.filter_parameters += [ :password, :secret, :token ]
```
Note that it's a plain Ruby file, and you have access to the Rails application and configuration objects.
Configuring these values inside an initializer provides a single place where you can add/remove them and avoids having to mix this functionality into the application code.
> P.S. To learn how parameter filtering works in Rails, check out the following article:
## Why use an Initializer?
You can use initializers to configure your Rails application or external gems. Initializers allow you to provide configuration settings that should be made after all of the frameworks and gems are loaded, such as options to configure their settings.
> Instead of writing the one-time initialization logic in your application code, use an initializer.
You can also use an initializer to set default values for your application and external gems. For example, here's the Delayed_Job initializer setting a bunch of useful defaults.
DelayedJob Initializer
I also asked about the different use-cases for Rails initializers on Reddit and received a bunch of great answers. Here're the main reasons people use initializers:
1. To set up one-time operations, like configuration of external gems
2. Anything that needs to happen before your app starts running.
3. Add monkey-patching code to overwrite a library you‘re using.
Rails ensures that the initializer code is loaded only once on startup and before receiving the first request.
If you know other use cases for them, please let me know in the comments below.
## How Rails Loads the Initializers?
At this point, you might be wondering: How does Rails picks up these Ruby files under config/initializers directory, and runs them when the application starts?
It does seem like magic, doesn't it?
The answer is: Code that loads the initializer scripts is an initializer itself, defined by the framework.
The initializer files in config/initializers (and any subdirectories of config/initializers) are sorted and loaded one by one as part of the load_config_initializers initializer.
```plain text
# railties/lib/rails/engine.rb
module Rails
class Engine < Railtie
initializer :load_config_initializers do
config.paths["config/initializers"].existent.sort.each do |initializer|
load_config_initializer(initializer)
end
end
end
end
```
In fact, the above snippet shows the other way to create an initializer using the initializer method. Let's take a look.
### The initializer method
The initializer method comes from the Initializable module, which is included by Rails::Railtie, the superclass of Rails::Engine class.
This method simply stores the passed blocks into a collection of initializers. Here's a simplified implementation:
```plain text
module Initializable
def self.initializer(name, opts = {}, &blk)
initializers << Initializer.new(name, &blk)
end
end
```
It takes three arguments:
1. The name for the initializer.
2. An options hash. The :before key in the options hash can be specified to specify which initializer this new initializer must run before, and the :after key will specify which initializer to run this initializer after.
3. A block. It's a piece of code to execute when the initializer runs.
Initializers defined using the initializer method will be run in the order they are defined in, with the exception of ones that use the :before or :after methods.
### Out-of-box initializers
Rails provides several initializers out-of-box that run on startup that are all defined using the initializer method. Here's an example of the assets_config initializer from Action Controller.
```plain text
module ActionController
class Railtie < Rails::Railtie
initializer "action_controller.assets_config", group: :all do |app|
app.config.action_controller.assets_dir ||= app.config.paths["public"].first
end
end
end
```
You can find a comprehensive list of all initializers in Rails on the official guides on configuring Rails applications.
But defining an initializer is only half of the process. How do all these initializers get executed? Who executes them?
Keep on reading...
## Executing Initializers: Rails Initialization Process
So far, we've only seen how to create initializers. However, simply defining an initializer is not enough. The initialization code needs to run for it to do something useful.
This section answers the question: How Rails executes the initializers?
What follows is a detailed explanation of the Rails initialization process, where Rails takes all the initializers that are included out-of-box, or those that you've provided, and executes them sequentially.
Here's a high-level sequence diagram you can refer to while reading the rest of the article.

Rails Initialization Process
All Rails applications use the config.ru file. This file is used by Rack-based servers, such as Puma, to launch the server and start the application.
> To learn more about Rack and config.ru file, check out
my detailed article on Rack
Step 1: The config.ru file requires the config/environment file.
```plain text
# config.ru
require_relative "config/environment"
```
Step 2: The environment file loads the Rails application and initializes it using the Rails.application.initialize! method.
```plain text
# config/environment.rb
require_relative "application"
Rails.application.initialize!
```
Step 3: The Rails.application points to your application's instance, defined in the config/application.rb file. The Application class inherits from the Rails::Application class, which provides the initialize! method.
```plain text
# config/application.rb
module Blog
class Application < Rails::Application
end
end
# railties/lib/rails/application.rb
module Rails
class Application < Engine
def initialize!(group = :default)
run_initializers(group, self)
end
end
end
```
The initialize! method calls this run_initializers method, as seen above. This is the method that grabs all the initializers and sequentially runs them.
However, you don't see the run_initializers method in the application.rb file. Where does it come from?
Answer:
- The Rails::Application class inherits from Rails::Engine, which inherits from Rails::Railtie.
- The Rails::Railtie class includes the Rails::Initializable module defined in the railites/lib/rails/initializable.rb file.
- The Rails::Initializable module provides the run_initializers method, which is included in your application class.
Here's the inheritance hierarchy of these classes.

Rails Application Inheritance Hierarchy
Here's a simplified implementation of the run_initializers method.
```plain text
# railties/lib/rails/initializable.rb
def run_initializers(*args)
initializers.each do
initializer.run(*args)
end
end
```
> In reality, it topologically sorts the initializers graph, based on the
```plain text
:before
```
```plain text
:after
```
And that's how Rails executes the initializers to configure your application and other gems. Once all the initializers have run, your application is ready to handle incoming requests.
## Summary
- An initializer is a piece of Ruby code under the config/initializers directory. You can use initializers to configure your Rails application or external gems.
- Rails makes sure that the initializer code is loaded during the initialization process, after loading the framework and any other gems, and before receiving the first request.
- Instead of writing the one-time initialization logic in your application code, you should use an initializer.
That's a wrap. I hope you liked this article and you learned something new.
As always, if you have any questions or feedback, didn't understand something, or found a mistake, please leave a comment below or send me an email. I look forward to hearing from you.
If you'd like to receive future articles directly in your email, please subscribe to my blog. If you're already a subscriber, thank you.