> Rails.env => "development" > Rails.env.development? => true

1. Change your configuration not a code

force_ssl if Rails.env.production?

development: enabled: true production: enabled: false test: enabled: true

force_ssl if Global.ssl.enabled

2. Use configurations over conditions

def main_page_title if Rails.env.production? "My App" else "My App #{Rails.env}" end end

development: main_page_title: "My App development" production: main_page_title: "My App" test: main_page_title: "My App test"

Global.text.main_page_title

3. Write code that means something

<%if Rails.env.production? || Rails.env.staging? %> <%end%>

development: tracking: enabled: false production: tracking: enabled: true staging: tracking: enabled: true test: tracking: enabled: false

<%if Global.marketing.tracking["enabled"] %> <%end%>

Conclusion

Usually Rails application has multiple environments – production, development, test and staging; and quite often application behaves differently in each environment. Rails provides a simple way to inspect current environment:But abusing Rails.env for adjusting application behaviour leads to serious issues with future configuration changes. We’ll discuss these issues below, along with the proper way to deal with them.Let’s say we want to force SSL protocol for user’s settings page. With Rails.env it’s easy to do, just place the following line into your UsersController:The main issue with this approach is that code is not flexible. Just when SSL should be forced for ‘staging’ environment, we should change the code. That’s not so difficult if condition is used only once, but in case when SSL is required in multiple places, it becomes pain in the neck.We can use YAML file to put all ducks in a row. Here’re SSL settings placed into ‘config/settings/ssl.yml’:I’ll use global gem to get OOP interface for this YAML:You can read more about global gem and configuration with it here .After this refactoring we can change behaviour without making changes in the code. To enable SSL for development environment, we should only enable option in YAML file. In case when this code was spread across different places, this approach saves a lot of time.In the new example, our application should provide different title on the main page for each environment:To avoid conditions we can replace this code with ‘config/settings/text.yml’:Now ‘main_page_title’ method is replaced with:Such declarative approach helps us avoid environment dependency in the code, removes batch of dump methods like ‘main_page_title’ and makes code more flexible.I found this piece of code in one of the projects:It was really hard to understand what this is and why it should be included only in production and staging environments until this commit message from the git log helped me: “Add tracking code to layout”Again, we put configuration into ‘config/settings/marketing.yml’:And the code looks like this:Now we can read it properly: “When tracking for marketing is enabled include this “magic” javascript”. Here we gain a very important value: code tells us about its intention.If you’re going to use Rails.env in your code, it’s time to think about configuration as it’ll help you make code: short, readable, and maintainable.