Contents

The Argument for Rails Application Templates

Introduction

While studying for job interviews I wanted to create several new Rails applications to test my knowledge. I found myself repeating the same steps over and over again: creating a new Rails project, installing gems, configuring the database, setting up authentication, and customizing the project structure. Wait. Why is it failing? Oh, I forgot to add the --database=postgresql flag. It was frustrating and time-consuming. That’s when I discovered Rails application templates. Here’s an example:

# $XDG_CONFIG_HOME/rails_templates/default.rb

def add_gems
  gem_group :development, :test do
    gem 'rspec-rails'
    gem 'factory_bot_rails'
    gem 'faker'
  end
  
  gem 'devise' if @using_devise
end

def get_user_input
  @using_devise = yes?("Do you want to add Devise for user authentication?")
end

def add_rspec_config
  initializer 'generators.rb', <<-CODE
    Rails.application.config.generators do |g|
      g.test_framework :rspec,
        fixtures: false,
        routing_specs: false,
        model_specs: false,
        helper_specs: false
      g.fixture_replacement :factory_bot, dir: 'spec/factories'
    end
  CODE
end

def add_devise = generate 'devise:install'
def add_rspec  = generate 'rspec:install'

# main setup
get_user_input
add_gems
after_bundle do
  add_devise if @using_devise
  add_rspec
  add_rspec_config

  # prepare the database
  rails_command 'db:drop db:create db:migrate db:test:prepare'

  git :init
  git add: '.'
  git commit: %Q{ -m 'Initialize repository' }
  
  say
  say 'Your Rails app is ready to go!', :green
  say
  say 'Next steps:'
  say "  $ cd #{app_name} && ./bin/dev", :yellow
  say
end

The template file is then provided as an argument when creating a new Rails app:

rails new myapp -m $XDG_CONFIG_HOME/rails_templates/default.rb

However, since I always wanted to use the same template with postgres and bootstrap options, it was easier to add the following shell function to my .zshrc file:

rails_new () {
  if [[ $# -eq 0 ]]
  then
    echo "Usage: rails_new <app_name>"
    echo "rails new \"\$@\" --css=bootstrap -T -d postgresql -m \$XDG_CONFIG_HOME/rails_templates/default.rb"
    return 1
  fi
  rails new "$@" --css=bootstrap -T -d postgresql -m $XDG_CONFIG_HOME/rails_templates/default.rb
}

Now I can create a new Rails app with the desired configuration by simply running:

rails_new myapp # plus any other options

That’s it! No more manual setup, no more forgetting to add the right flags.

A few additional features

  1. The location of the template can also be a URL. This is useful for sharing templates across teams or projects.

  2. You can define custom generators, such as for controllers, models, or scaffolds, to further customize the project setup.

  3. Application templates can also be applied to existing projects to add new configurations or dependencies. This might be useful if you need to update mulitple projects. In that case, the command would look like this:

    rails app:template LOCATION=~/project_zebra_updates.rb

Check out the Rails Guide for Application Templates for more information.