New Rails Template
In this article we take a look at a more complete Rails template, to start a new Rails project. Why? With a custom template, you can start developing your project immediately already preconfigured with the gems, packages, and settings you like to use.
Credit
The inspiration for my custom template starts with Andy Leverenz's Kickoff template. There are a few other great resources as well.
Jumpstart Chris Oliver has put together a template called Jumpstart. This template creates a Boilerplate app that includes user accounts, admin interface, and Bootstrap styling.
Jumpstart Pro Chris also has a commercial product called Jumpstart Pro that bootstraps a full featured e-commerce application setup.
Template Features
- User accounts with Devise, friendly_id, and name_of_Person
- Sidekiq
- Testing environment with RSpec, Guard, Simplecov, and Rubocop
- User Avatars using Active Storage, with a fallback image using Gravatar
- Tailwind for styling
- Fontawesome
- Stimulus JS and
tailwindcss-stimulus-components
for the dropdown menu action
TL;TR: The completed repository to the finished custom rails template if you would like to jump straight to the code.
Using a Template
First let's cover the basics of using a template. The rails new
command offers many command option flags, and provides a flag to use a custom template:
rails new myapp -m /path/to/my/template.rb
I had written on this topic previously in Rails Boilerplate. When this command is executed, Rails will run the script, install and create the new app.
Now, to streamline this process you can create a dotfile in the root of your file system: .railsrc
. Rails will look for this configuration file first. In our case this is a good start:
--database=postgresql
-T
-m /path/to/my/template.rb
So, we can start the new project: rails new myapp
. Rails will use Postgres database, will not install a testing framework (more on this later), and use our template, without having to type the commands on the command line.
If at some time you wan to create a default Rails app, instead of your custom setup: rails new myapp --no-rc
.
A Custom Template
If you start to look at the main template.rb
in the codebase you will notice at the top of the file is a series of methods, and the business logic of calling these methods:
# Main setup
source_paths
add_gems
after_bundle do
stop_spring
add_testing
add_active_storage
add_users
remove_app_css
add_sidekiq
add_foreman
copy_templates
add_tailwind
add_fontawesome
add_stimulus
add_friendly_id
copy_postcss_config
add_stimulus_navbar
# Migrate
rails_command "db:create"
rails_command "db:migrate"
git :init
git add: "."
git commit: %Q{ -m "Initial commit" }
Basically, after the bundle install
in completed the methods are executed, it creates the database, a migration is run, and then the first git commit
is saved.
So, let's go over a few of the methods to show you the power of the API.
Add gems
The add_gem
method does not install these gems, it only adds the gems to the Gemfile. If you examine the method you will notice we are setting up gems associated with users, setting up a testing environment, and Rubocop.
def add_gems
gem "devise", "~> 4.7", ">= 4.7.2"
gem "friendly_id", "~> 5.3"
gem "image_processing"
gem "sidekiq", "~> 6.1", ">= 6.1.1"
gem "name_of_person", "~> 1.1", ">= 1.1.1"
gem_group :development, :test do
gem "database_cleaner"
gem "factory_bot_rails", git: "http://github.com/thoughtbot/factory_bot_rails"
gem "rspec-rails"
end
gem_group :development do
gem "fuubar"
gem "guard"
gem "guard-rspec"
gem "rubocop"
gem "rubocop-rails", require: false
gem "rubocop-rspec"
end
gem_group :test do
gem 'simplecov', require: false
end
end
NOTE: After your app is set up you will probably want to clean up your Gemfile. All the above gems and groups are added to the bottom of the Gemfile.
If you have been following my articles you know I have written about this Rails Testing Setup before.
Testing
I noted previously, in the .railsrc
file, we did not install the default Rails testing environment. In the add_testing
method we are setting up Rspec.
def add_testing
generate "rspec:install"
directory "spec", force: true
run "rm -r test" if Dir.exist?("test")
copy_file "config/webpacker.yml", force: true
copy_file ".rspec", force: true
copy_file ".rubocop.yml"
copy_file ".simplecov"
copy_file "Guardfile"
end
Remember, this method will run after bundle install
, so we are only configuring the gems here. Since we are using a repository, instead of just a simple template file, we can copy preconfigured files and directories:
- We are copying the
spec
directory and force overwriting the directory in the new app. - In case the user does not have -T in the
.railsrc
file, we are deleting thetest
directory if it exists.
You can read more about the Template API at Railsguides.
Modifying Files
In the creating process we can also modify files. For instance, in the add_tailwind
method:
append_to_file("app/javascript/packs/application.js", 'import "stylesheets/application"' + "\n")
inject_into_file("./postcss.config.js",
"let tailwindcss = require('tailwindcss');\n", before: "module.exports")
inject_into_file("./postcss.config.js", "\n tailwindcss('./app/javascript/stylesheets/tailwind.config.js'),", after: "plugins: [")
In this case we can append_to_file
an import. Also, we are injecting into a file at a specific point (before of after some text).
We can also inject at the end of a file a block of inserts:
inject_into_file 'app/javascript/controllers/index.js' do
<<~EOF
// Import and register all TailwindCSS Components
import { Dropdown, Modal, Tabs, Popover, Toggle } from "tailwindcss-stimulus-components"
application.register('dropdown', Dropdown)
application.register('modal', Modal)
application.register('tabs', Tabs)
application.register('popover', Popover)
application.register('toggle', Toggle)
EOF
end
The Template API is fairly robust and offers a way to streamline the startup time of a new project. This is my personal setup. Clone the repository and give it a try, tweak it for your own, and if something doesn't work, open a PR.
Footnote
This has been fun. Leave a comment or send me a DM on Twitter.
Shameless Plug: If you work at a great company, and you are in the market for a Software Developer with a varied skill set and life experiences, send me a message on Twitter and check out my LinkedIn.