Flavio Antelo
Flavio Antelo

Flavio Antelo

How Do I Start My Rails Projects in 2021

How Do I Start My Rails Projects in 2021

Spoiler: Bootstrap, simple_form, Heroku, slim, parity, rubocop, prettier

Subscribe to my newsletter and never miss my upcoming articles

Hello there! My name is Flavio. I've been working with Rails since 2011 and every time I start a new rails project, I go through pretty much through the same setup. Of course it evolves over time, but the core stays the same. I'm writing this post so I can benefit from it myself, but I'm also sharing it with you, in the hope that you can find some use of it!

Init the project and the GitHub repo

There's nothing fancy here. Just launch the regular rails new command with no options attached.

rails new $YOUR_APP_NAME
cd $YOUR_APP_NAME
git add .
git commit -m 'first commit'
hub create -p # to create a private repo on GitHub
git push origin master

This will install the basic Rails boilerplate project, including webpacker, active storage, and company. It'll use sqlite3 as database, which is exactly what I want for now, even though we'll change it to postgres later.

Install and customize Bootstrap

I almost always add the following dependencies to my projects:

# add support to bootstrap 
yarn add bootstrap@4.6.0 jquery popper.js

# import bootstrap from app/javascript/css/application.scss
# and, optionally, you can override variables before the import, for instance:
$blue: #0596de;
@import "~bootstrap/scss/bootstrap.scss";

For an extensive list of all available variables: github.com/twbs/bootstrap/blob/main/scss/_v..

Then finally import Bootstrap JS and its JS dependencies (in this order):

# app/javascript/packs/application.js
import "bootstrap";
import "css/application"; # this is the file we've just created above
import "jquery";
import "popper.js";

I also like to add a custom script into the package.json file:

  "scripts": {
    "dev": "./bin/webpack-dev-server"
  }

Setup simple_form with Bootstrap

bundle add simple_form
rails generate simple_form:install --bootstrap

Adapt layouts to slim

app/views/layouts/application.html.slim 🔻

doctype html
html
  head
    title Immobilier
    meta name="viewport" content="width=device-width, initial-scale=1.0"

    / = render 'layouts/shared/favicon'
    = csrf_meta_tags

    / = render 'layouts/shared/google_tag_manager_head' if Rails.env.production?
    = stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload'
    = javascript_pack_tag 'application', 'data-turbolinks-track': 'reload'

  body
    / = render 'layouts/shared/google_tag_manager_body' if Rails.env.production?
    = render 'layouts/shared/navbar'

    .container.pt-4.pb-5
      = render 'layouts/shared/alerts'
      = yield

app/views/layouts/shared/_navbar.slim 🔻

nav.navbar.navbar-expand-lg.navbar-light.bg-light.py-4
  .font-weight-bold
      = link_to 'Immobilier', '/', class: "navbar-brand ml-3"
  button.navbar-toggler aria-controls="navbarSupportedContent" aria-expanded="false" data-target="#navbarSupportedContent" data-toggle="collapse" type="button"
    span.navbar-toggler-icon

  #navbarSupportedContent.collapse.navbar-collapse
    ul.navbar-nav.ml-auto
        li.nav-item
          = link_to 'Subscribe', '/', class: 'btn btn-outline-primary mx-3'
        li.nav-item.dropdown.mx-3
          a#navbarDropdown.btn.btn-light.dropdown-toggle aria-expanded="false" aria-haspopup="true" data-toggle="dropdown" href="#" role="button"
            = 'User Name'
          .dropdown-menu.dropdown-menu-right aria-labelledby="navbarDropdown"
            = link_to 'Edit Profile', '/', class: 'dropdown-item'
            = link_to 'Settings', '/', class: 'dropdown-item'
            .dropdown-divider
            = link_to 'Sign Out', '/', method: :delete, class: 'dropdown-item'

app/views/layouts/shared/_alerts.html.slim 🔻

- if notice
  .alert.alert-primary.alert-dismissible.fade.show
    = notice
    button.close data-dismiss="alert"
      span aria-hidden="true" ×

- if alert
  .alert.alert-danger.alert-dismissible.fade.show = alert

Setup Linters

Prettier JS

.prettierrc 🔻

printWidth: 120
semi: false
singleQuote: true
trailingComma: es5

Prettier Ruby

Just add the ruby prettier plugin as a dev dependency:

yarn add @prettier/plugin-ruby --dev

And enable auto-format on save on VS Code .settings.json file:

// autofix JS on save
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",

Rubocop

TBD: I really struggle finding an easy way to share the same rubocop config across different projects without having to copy and past the rubocop.yml file everywhere every time you make an update. Do you have a solution for that? Please leave a comment below 🙏

UPDATE: Following Adrien Lefebvre's comment below...

Now I start my projects with a one-line .rubocop.yml file:

# source: https://github.com/fwuensche/antelo-linters/blob/main/.rubocop.yml
inherit_from: https://raw.githubusercontent.com/fwuensche/antelo-linters/main/.rubocop.yml

And I maintain the shared rubocop config in a public GitHub repo: github.com/fwuensche/antelo-linters

Setup database for production

When I want to move fast, I tend to go with sqlite for development and tests - because its setup is super simple - and with postgres for production - because that's the required db by Heroku.

group :development, :test do
  gem 'sqlite3'
end

group :production do
  gem 'pg'
end

Deploy to Heroku

If you didn't install and login yet:

brew install heroku/brew/heroku
heroku login

Then I create my app with:

heroku create $YOUR_APP_NAME --region eu

And I like using the parity gem by thoughtbot to manage my heroku apps:

brew tap thoughtbot/formulae
brew install parity

You'll need to setup your git remotes:

heroku git:remote -r staging -a your-staging-app
heroku git:remote -r production -a your-production-app

And upload your credentials master key as an environment variable:

heroku config:set RAILS_MASTER_KEY=f068bdba0b9ff1038611f0d92fcc3cb7

So you can now run things like:

production deploy
production migrate
production console
production tail
development restore-from production

Release phase

For simplicity, you can enable auto deploys on Heroku. All you need is to connect your GitHub project and, once you push to master, Heroku will automatically deploy the application for you.

image.png

On the other hand, by default, Heroku won't run new migrations and you might forget to do that on your own. To avoid this kind of issue, you can add a file named Procfile to the root of your project:

web: bundle exec puma -C config/puma.rb
release: rake db:migrate

With that you should be safe as migrations will be run before the new version of your application is released to your users.


Are you into productivity hot tips for web development? I'm a Brazilian full-stack developer, living and working in Paris, and I regularly share articles like the one you've just read. Follow me on twitter.com/whosantelo to stay tuned.

 
Share this