My most useful rails' configuration

Often enough, I spend hours debugging something in my application stack to end up learning that I could have changed a setting in the configuration and call it day. There's many reason why I don't have the reflex to check the configuration more often:

Today, I won't fix the problem of the universe. Yet, I'm sure you will find something useful that you either didn't know about or forgot that you could use. Unless noted otherwise, the following settings can be either set in config/application.rb or in config/environments/{env}.rb.

Let's start.

config.console(&block)

This one is really useful if you want to use Pry with rails' console. Whatever you specify there will executed only when calling rails console.

# config/application.rb
config.console do
  require 'pry'
  config.console = Pry
end

config.exceptions_app=(app)

The default way rails handle exceptions in production is to render the page in /public/500.html. That is a static page. What if you want to render some dynamic content, or you want to handle the exception in a more graceful way like a redirection with a flash message?

This setting let you do just that. The exceptions_app is any rack capable middleware. If you've followed this blog recently, you know that an ActionController::Base is a rack middleware. So you can do something like this:

# config/environments/production.rb
config.exceptions_app = ErrorController.action(:handle)
# app/controllers/error_controller.rb
class ErrorController
  def handle
    flash.alert(t(".message"))
    redirect_to :back
  end
end

config.filter_parameter=(*params)

Filter parameter is something that you must set if you deal with credit card number. It replaces the value of any specified parameter with "[FILTERED]" so your log can't be mined for user information. Imagine if your logs had every credit card numbers. Don't be that guy. Filter sensitive data.

The parameter you pass do not need to be an exact match. Rails uses regexp to find matches. So if you specify "password", rails will filter password, password_confirmation, etc.

# config/application.rb
config.filter_parameter = %w(password credit)
# This will filter any parameter containing the word password OR credit in any order in the key.

config.i18n.load_path=(paths)

When I first started, I18n was putting me off because I loathed the fact that every translations were set in the same file. I like to have a nice hierarchy in my translations files that reflect the controller I'm in.

For example, I would have something like posts/fr-ca.yml for any translation made within PostsController.

Here's how you include any .yml file inside your config/locales folder:

# config/application.rb
# '**' means recursions!
config.i18n.load_path = Dir[Rails.root.join('config', 'locales', '**', '*.yml')]

You can now have different YAML files organized in a neat way. The way you organize your YAML folder is entirely up to you. Rails will load all the files inside config/locales and create a Hash in memory. If you set the same key in two different files, Rails won't alert you and it will select the one it loads last.

# config/locales/posts/en.yml
en:
  posts:
    message: "Hello world!"
# config/locales/users/en.yml
# Setting en.posts.message would replace the one set in the previous example!
en:
  users:
    welcome: "Welcome home, %{name}"

config.i18n.default_locale=(:en)

Sometimes I have to switch the default locale as I am french canadian and some of the sites I work on are french. Even though I don't plan on having the site translated into different language, I like using i18n as it keeps my code base clean and it gives separation of concerns between the logic and the messages.

By default, Rails is configure to use en as the default locale.

This is usually commented out on application.rb so you probably already know about it.

# config/application.rb
config.i18n.default_locale :'fr-CA'
# will look in config/locale/fr-CA.yml

config.action_dispatch.default_headers=(hash)

I've never used this option before but I still think it can be useful to some of you so here it is. By default, Rails has a few headers set and you can add your own too.

# config/application.rb
config.action_dispatch.default_headers['X-My-Header'] = 'some value'

# defaults to:
# 'X-Frame-Options' => 'SAMEORIGIN'
# 'X-XSS-Protection' => '1; mode=block'
# 'X-Content-Type-Options' => 'nosniff'

config.to_prepare(&block)

This one I use often. It can be very useful in development mode when you are building something outside of rails' normal flow. The best example I have is when creating strategies for Warden. I create my strategies and put them in app/strategies/password_strategy.rb. To register your strategy with Warden, you have to do Warden::Strategies.add(:password, PasswordStrategy).

Because the class is stored in a hash and that hash is not purged after every request in development like the rest of the environment stack, the pointer held in the hash points to a non existant constant. So your application crash. First time it happened I wasted a few hours understand the root of this problem. So, instead of restarting your server at every request to build your strategy, you can use to_prepare to fix the issue.

# config/application.rb
config.to_prepare do
  Warden::Strategies.add(:password, PasswordStrategy)
end

Notice that I use to_prepare in application.rb, not in an environment file. The reason for doing so is that to_prepare is only called once in production while it's called before every request in development.

So, if you have something you want to do in your project and you always have to restart your project for one reason or another in development, using to_prepare might be what you need.

config.action_view.field_error_proc

I really hate how this thing work. When I build form, I often use the CSS descendant operator (>) to specify something. Because ActionView wraps field with errors in a classless <div>

Personally, I love form builders and I usually generate my errors there. Even if it can mean that I have to write more code, I like to be able to personalize the error as it gives me flexibility and I can change the way I present errors depending on the context.

Anyway, whether you want to add a class to the wrapping container or you want to entirely remove the container, it's possible by changing the proc on this setting.

# config/application.rb
config.action_view.field_error_proc = Proc.new do |html_tag, instance|
  %Q(<div class="my_custom_error_class">#{html_tag}</div>).html_safe
end

Or

# config/application.rb
config.action_view.field_error_proc = Proc.new do |html_tag, instance|
  html_tag
end

config.action_mailer.raise_delivery_errors

I've had issues with this one before and it drove me CRAZY. In development mode, this value is set to false which mean if you try to send yourself a test e-mail in development just to make sure it works and it actually doesn't, Rails will just go about it's business, return 200 OK and you will go mad thinking that everything went according to plan even though you don't receive any e-mail.

Long story short, if you want to test your e-mail delivery mechanism on localhost, you want to modify config/environments/development.rb and switch this setting to false.

# config/environments/development.rb
config.action_mailer.raise_delivery_errors = true

What are the configuration options you like?

Now that I've talked about the config files I like the most, what are yours? Any that I haven't mentioned that you couldn't live without? Hit the discussion below!