Rails 6 web app quick start guide (react, bootstrap, fontawesome, and more)

Petro Podrezo
8 min readDec 24, 2019

I wanted to put together a guide on how to get started with my typical set up for a new rails web application project, mostly for myself to refer back to as a kind of checklist for how to quickly get going with my usual tooling, but I figured it would be helpful for others as well, so without further ado, let’s go!

Prerequisites

  • Node.js (for webpacker to run)
  • Yarn (used by webpacker to install dependencies)
  • Visual Studio Code (I’ll explain how to set up debugging in it)
  • Ruby (does this really need to be said?)
  • Rails installed globally (in order to use the “rails new” generator)

Creating the base project

rails new $YOUR_NEW_PROJECT_FOLDER --webpack=react

(I would also recommend to add —-database=postgresql --skip-action-cable if it makes sense for your use-case)

After this is done, this is a good point to commit your changes so you can track what modifications you made to your project after the generator was finished.

Freshly generated rails site

You should be able to successfully launch the server at this point if you want to just test that we’re good to continue, using the usual rails s :

Rails 6 running with the default landing page

From this point forward, after any step is complete if you see odd results when viewing it in the browser, try restarting the rails server — while rails does monitor for changes automatically, sometimes it does not pick up changes to certain gems until restarted.

Adding debugging support with vscode

As a good developer, you’ll probably want to add support for breakpoints, stack traces, and more. First, you’ll need to add some development gems:

bundle add ruby-debug-ide --group development
bundle add debase --group development

Then, open .vscode/launch.json , you can do this from the command palette. If prompted for a type of launch, choose anything — we will be replacing it anyway.

Command palette showing launch.json

Add the following entry to your configuration(s):

{
"version": "0.2.0",
"configurations": [
{
"name": "Rails server",
"type": "Ruby",
"request": "launch",
"program": "${workspaceRoot}/bin/rails",
"args": [
"server"
],
"cwd": "${workspaceRoot}",
"useBundler": true
}
]
}

You should now be able to start the rails server and create breakpoints. Note that using this configuration will require the “Ruby” and “Rails” extensions for vscode.

We’ve got debugging support in the menu

Create a homepage

In order to test out if React is working properly, we’ll want to create a page to work on. Let’s generate a new controller for the homepage

rails g controller Home

Then create a view at app/views/home/index.html.erb ; you can populate it with anything for now, even a blank file. Then let’s point the rails root route to it in config/routes.rb

Rails.application.routes.draw do
root "home#index"
end

You should be able to see your page in the browser (you may need to run rails webpacker:compile first):

Our new home page

Adding first class ReactJS support

While we did tell rails we want react support out of the box, there’s some things we can do to make our lives easier. For that purpose, there’s the react-rails gem as well as the actual react javascript libraries via yarn. Let’s add it, and run the generator to add react support through it:

bundle add react-rails
rails generate react:install
yarn add react react-dom
yarn add @babel/preset-react prop-types --dev

Add ‘@babel/preset-react’ to your babel.config.js file under the “presets” section:

// ...
presets: [
'@babel/preset-react',
// ...

This will now allow us to generate react component stubs. For more information on the various options, check the gem’s documentation. Let’s make a stub for a HelloWorld component that displays a greeting:

rails generate react:component HelloWorld greeting:string

This will generate app/javascript/components/HelloWorld.js as follows:

The new HelloWorld react component

Now in order to test that we can display it properly, open the home page index view we created in the previous section and add the following to it:

<%= react_component("HelloWorld", {greeting: 'test greeting'}, {prerender: true}) %>

What this will do is render that same HelloWorld component, pass it the props that are specified in the second argument, and we tell rails to pre-render the initial display of that component on the server side so that it is fully ready to display to the user upon loading page. You should be able to refresh the browser and see “Greeting: test greeting” in it if everything went correctly. If your entire page is a react component, you can avoid having to create the ERB view for it and just tell the controller to render the react component directly like so:

class HomeController < ApplicationController
def index
render(component: 'HelloWorld', props: { greeting: 'test 123' })
end
end

One little thing I also like to add is to change my generated react component files from a “.js” extension to “.jsx” — this may require adding a line to config/webpacker.yml to allow that, so under default → extensions in that file, add a line that says-.jsx after the line that says - .js if it is not already there.

Adding Bootstrap for style

I’ve used other CSS frameworks before, but I always find myself coming back to Bootstrap since it is so well documented, looks polished, and has great support for extensions. To add bootstrap to your project we can install the gem for it:

bundle add bootstrap

We’ll also need to install the actual javascript libraries

yarn add bootstrap

You’ll want to make sure your versions match up, and you will need both of these steps for it to work. At this point, I would recommend changing the extension of app/assets/stylesheets/application.css to “scss” and then adding a line to it that says

@import "bootstrap";

Now let’s test that it works by modifying our homepage HTML to something like this:

<section class="jumbotron text-center">
<div class="container">
<h1>Hello, world!</h1>
<p class="lead text-muted"><%= react_component("HelloWorld", {greeting: 'test greeting'}, {prerender: true}) %> </p>
<p>
<a href="#" class="btn btn-primary my-2">Main call to action</a>
<a href="#" class="btn btn-secondary my-2">Secondary action</a>
</p>
</div>
</section>

Which should produce this nice, bootstrap-styled page showing us it’s working:

Bootstrap example working, with react inside

Adding FontAwesome icons

As before, add the appropriate gem — in this case I recommend “font-awesome-rails”.

bundle add font-awesome-rails

Add the following import to your application.scss :

@import "font-awesome";

And now let’s change our button from our home page to use an icon:

<a href="#" class="btn btn-primary my-2"><%= fa_icon "camera-retro fw" %> Take a photo</a>

You should now be able to see a camera icon:

Camera icon showing up correctly

Use UUIDs for model identification by default

By default, rails uses numerical identifiers for models and their relationships. This is generally fine, and there are definitely good reasons not to use UUIDs as your primary key but I’ve been bitten one too many times by building systems where I end up having to retroactively outfit models in my database with UUID keys after the fact in order to integrate with other systems so I’ll add this section to save you the headache.

If you’ve been following this guide from the start, you probably still have no database so create it:

rails db:create

In your config/application.rb add the following

config.active_record.primary_key = :uuid
config.generators do |g|
g.orm :active_record, primary_key_type: :uuid
g.orm :active_record, foreign_key_type: :uuid
end

If you’re using postgres for your database you’ll need to enable the appropriate extension like so:

rails g migration enable_pgcrypto_extension

If that command does not populate the migration file automatically, just make it read as follows:

class EnablePgcryptoExtension < ActiveRecord::Migration[6.1]
def change
enable_extension 'pgcrypto'
end
end

Now let’s add a model to test with:

rails g model Post

And migrate the changes

rails db:migrate

You should notice the output mentions that we’re using UUIDs

== 20191222155952 CreatePosts: migrating ======================================
-- create_table(:posts, {:id=>:uuid})

If you hop into the rails console you should be able to create new models with UUIDs. Note that if you’re using sqlite for your database, it will not automatically populate the UUID for you in a new model instance and you’ll have to “manually” generate it. Here’s what I mean:

sqlite will not set the UUID for you, you must do it yourself

Notice the part where I tried to save the model and it failed due to having a null value for the ID. You can use the “securerandom” library to generate a UUID, set it on the id field, and save the model successfully.

require 'securerandom' 
p = Post.new(title: 'hello world')
p.id = SecureRandom.uuid
p.save

More info can be found at this blog post on the subject of UUIDs in Rails models.

Next Steps

This guide should get you to a great starting point to actually start building out functionality and business logic. If you’ve followed the whole guide you should have a snappy looking Bootstrap-themed rails web app, with beautiful FontAwseome icons, full debugging support, and be ready to generate models with UUIDs. I hope you found use from this guide, and as a potential next step you may want to consider adding the “devise” gem if you’re going to have users and accounts to authenticate with for your application (I added a very brief quickstart for it below). Good luck!

Adding Devise for User Management

Add the gem and run the installer:

bundle add devise 
rails generate devise:install

Add flash notices somewhere (e.g. application.html.erb)

<p class=”notice”><%= notice %></p> 
<p class=”alert”><%= alert %></p>

Generate the database model

rails generate devise ${MODEL e.g. ‘User’} 
rails db:migrate

Your login pages will now be accessible at routes like /users/sign_up.
To customize the views you can use rails g devise:views and then edit the generated HTML files.

--

--