Red Green Repeat Adventures of a Spec Driven Junkie

Ruby on Rails Template for Consistent Applications You Want

Ever want to just start a Ruby on Rails project quickly? Just to try something in a “clean slate”? Where you have you have your “best practice” stuff setup and get rid of all the default stuff?

I show you my solution to setting up a Ruby on Rails application your way by going over the mechanics of configuring the Ruby on Rails template file and Ruby on Rails configuration file I use.

You will learn about Ruby on Rails template and the Ruby on Rails configuration file.

This article will take you about six minutes to read.

Maison Léoty - Corset source and more information

Introduction

A Ruby on Rails application has numerous options when making a new application configured by default, such as:

  • a test framework
  • a database
  • boot-loaders
  • front-end support
  • mailers
  • web-sockets

All of these are great and I appreciate the default Ruby on Rails application configuring these for me.

At the same time, the options configured are numerous. I also have opinions of my own. I just want something simple, backend server, such as:

  • PostgresSQL as my database
  • API only (no front-end support)
  • Rspec as my testing framework

At the same time, also having best practices for any application that may or may not roll into production, such as:

  • code linter
  • swagger / API documentation system
  • performance monitors
  • n+1 checkers

Detangling

Given that Ruby on Rails has its own defaults and I have my preference, I may spend a significant amount of time detangling rails new to my idea of “clean slate” can more time than my original goal.

This is time that I could have just used coding into the current or another configured app.

What’s even crazier, is that as of this writing: Ruby on Rails 6.1.3 using rails new fails - sass-rails causes build error, (the workaround: change the Gemfile for gem 'sass-rails', '= 5.1.0')

If I can setup a “development computer” with my favorite editor configured, can I setup “backend framework” with my favorite pieces configured?

Ruby on Rails Template

Fortunately, there’s a solution where one won’t have to do all of this “detangling” with every new Ruby on Rails project, they would have to sit down once, detangle into a template, and reuse the template every time.

The official documentation is here

The template file can be any Ruby file and it has specific options. To use the template:

  • New Ruby on Rails applications would pass the file in as an option:

    rails new <new app name> -m <template filename or URL>

  • Existing Ruby on Rails applications would run the following command in an existing Rails project:

    rails app:template LOCATION=<template filename or URL>

The template can be a filename OR a URL.

gems & Gemfiles

In the template, to include gems you want (in addition to anything configured) you can add them using a gem_groups option or just add them as a gem:

gem "<your favorite gem>"

Any entries made in the these only add gems. The existing Ruby on Rails default will still be there (I’m looking at you tzinfo-data!)

If you want to override gems, say use PostgreSQL instead of SQLite, that would be better accomplished by the --database= option in the railsc option.

gem_group

If you would like specific gems for production, development or test, place these gems into a gem_group to have them grouped nicely for your specific use cases.

The gem_group will NOT overwrite any existing group in the file, the gem_group option is purely additive, at the end of the default Gemfile produced.

Do not expect:

gem_group :development, :test do
  gem 'pry'
end

to overwrite the default:

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end

Both sets will exist in the Gemfile as:

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end

# ...

gem_group :development, :test do
  gem 'pry'
end

If you want to get rid of the default, I found the best thing to do is manually remove it after creation.

Commands

Need to run a specific command? There are two options:

  • Ruby on Rails specific commands, like generate model/controller/etc. or migrate, use:
rails('<rails specific command>')
  • Regular commands, such as those would be for a gem or system command:
run('<command>')

after_bundle

This is an option to have specific actions taken after bundle completes installation of gems:

after_bundle do
  rails_command("generate rspec:install")
  run("rubocop -A")
end

I like having Rspec configured and Rubocop clean things up on a fresh install.

Preconfigure files

For any files you want to be in the application, such as a Rubocop configuration, you would specify in the template as:

file '<filename>', <<-FILECONTENTS
filename contents
FILECONTENTS

This create the file in the application folder with the specified contents.

.railsc

There are additional switches rails new accepts and you have to specify them outside of the template file and in the .railsc file.

The file are a list of options the rails new --help accepts.

This is where to specify your Ruby on Rails project uses PostgreSQL instead of SQLite (as Ruby on Rails make more changes for it.)

--database=postgresql	# Configure Rails to use postgresql

Making it all Work Together

Let’s take a Ruby on Rails template file, a .railsc and create a new application with them.

Template file

This is the template file I will use for all of my new Ruby on Rails applications.

# usage: `rails new <app name> -m ~/rails_template.rb --api --database=postgresql`

gem_group :development, :test do
  gem 'bullet'
  gem 'factory_bot'
  gem 'pry'
  gem 'rspec-rails'
  gem 'rubocop-rails'
  gem 'rubocop-rspec'
end

gem_group :development, :production do
  gem 'rails_performance'
end

file '.rubocop.yml', <<-RUBOCOP_CONFIG
Documentation:
  Enabled: false

Style/FrozenStringLiteralComment:
  Enabled: false
  EnforcedStyle: never
RUBOCOP_CONFIG

after_bundle do
  rails_command("generate rspec:install")
  run("rubocop -A")
end

Configuration file

This is the .railsc configuration I use:

--api					# API only
--database=postgresql	# Configure Rails to use postgresql
--skip-bootsnap			# skip bootsnap
--skip-spring			# skip spring
--skip-sprockets		# skip sprockets
--skip-test				# skip minitest - I prefer rspec

Running it

This is the command I use with the above template and configuration file:

rails new <app name> -m ~/rails_template.rb

Conclusion

The frustration of detangling defaults for a Ruby on Rails application is no more with Ruby on Rails template and the configuration file. Whenever I need a new Ruby on Rails application for production OR even just try something out, I can create it with ease.

References

Thanks to this article for showing specific details!