Rails 5 with Bootstrap Using Rails-Assets Gem

Frontend asset management can be a pain. The rails-assets gem makes it simple to include frontend javascript and css frameworks in your Rails project. It converts the packaged components (css and javascript) into gems that are dropped into the asset pipeline. This article explains why you should use the rails-assets gem and how to use it to get Bootstrap going with your Rails app.

Before the days of the JS framework wars building a dynamic site was as simple as downloading Bootstrap and JQuery and adding them to you project as static assets. The remaining Javascript and CSS assets were all contained within your project and simple to manage with the asset pipeline. Package management for these components wasn't a concern since the client side code was fairly straight forward and not changing much.

Then frontend code started to get more complex. The number of exeternal dependencies started to grow. More so, their interdependencies started to grow as well. The first pain point I remember having was when I added twitter's typeahead module to a project. The Bootstrap version I was using didn't have the correct classes to make the dropdown with typeahed suggestions visible. To resolve the problem I spent several days in forums and reading the source code to figure out how to hack the Bootstrap version I was running to get the typeahead working and visible.

Goals of asset management

The two things I want when I include an external piece of software in a project are:

What I'd really like is something more like bundler so I can declare my dependencies and leverage semantic versioning to specify the types of package upgrades I'd like to receive e.g. patch releases and minor releases. This way I can get security and bug fixes while trusting the api's of my dependencies aren't changing and just let the package management system "figure out" how to meet the dependency requirements.

Approaches to asset management

For simple client side applications where the vendored assests rarely change manually packaging things isn't the worst approach. However, as the complexity of frontend applications grows I become increasinly wary of foisting this burden upon the poor souls that maintain a project after I'm gone. Here are a few concerns:

Asset gems

When I first came to Rails one of the things I loved was asset gems. I thought "Wow, managing static assests with ruby dependencies what could be better!" Other projects I had worked on in Django and PHP used the manual approach. I was sold, for awhile.

The approach has a couple of obvious weaknesses.

Modern Frontend Package Managers

Options are many and include -

Quite honestly, I have no idea which approach will win or why. I don't feel it's necessary to pick a winner now. I'll be satisfied with a solution that tries to give me bundler-esque functionality for frontend libraries in a ruby envelope.

For our purposes we don't need pure node package management, our target environment is the browser. Bower was designed with that goal in mind and it's the tool that rails-assets uses to do it's dependency management.

Walkthrough

Here we'll show how to add Bootstrap (or any other frontend assets available through rails assets) to a Rails project in under 5 minutes.

Create the Rails project

 $> rvm get stable
 $> rvm list
 $> rvm use 2.3.0@tmwsd --create
 $> gem install bundler
 $> gem install rails
 $> rails new tmwsd
 $> cd tmwsd
 $> echo 2.3.0 > .ruby-version
 $> echo tmwsd > .ruby-gemset
 $> cd dev/rails/tmwsd
 $> git init .
 $> git add .
 $> git commit -m 'rails new tmwsd'
 $> rails s

Visit http://localhost:3000 in a browser and you get the stock rails UI.

Stock Rails UI

Specify the top level layout for the application

We want most of our sites pages to have a common appearance. This will include Bootstrap by default in all those pages.

# app/controllers/application_controller
class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception

  layout "application"
end

Add a new controller called Main.

# app/controllers/main_controller.rb
class MainController < ApplicationController
  def index
  end
end

Set the root document to be handled by the new controller's index action.

Rails.application.routes.draw do
  root 'main#index'
end

Add the view for the main#index

<h1>Hello Rails 5</h1>
<p>Let's make apis</p>

Refresh your browser

standard layout

Add Bootstrap

Now it's time to add bootstrap into the project. Visit the rails-assets website and search for the Bootstrap library. Click the install link and the following instruction tell you to:

Add the rails-assets-bootstrap gem to the Gemfile

diff --git a/Gemfile b/Gemfile
index 7b8b938..fa2789b 100644
--- a/Gemfile
+++ b/Gemfile
@@ -31,6 +31,7 @@ gem 'jbuilder', '~> 2.5'
# gem 'capistrano-rails', group: :development

+gem 'rails-assets-bootstrap', source: 'https://rails-assets.org'

Bundle

 $> bundle

Add bootstrap to the stylesheet and javascript manifests

Add this line at the top of the javascript and css manifests

diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index b12018d..74acbb9 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -10,6 +10,7 @@
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
+//= require bootstrap
//= require jquery
//= require jquery_ujs
//= require turbolinks
diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css
index 0ebd7fe..c2864ab 100644
--- a/app/assets/stylesheets/application.css
+++ b/app/assets/stylesheets/application.css
@@ -10,6 +10,7 @@
* files in this directory. Styles in this file should be added after the last require_* statement.
* It is generally better to create a new file per style scope.
*
+ *= require bootstrap
*= require_tree .
*= require_self
*/

Refresh your browser

Standard Layout

Continued Community Support

The rails-assets gem has recently undergone a change in hosting and maintenance. In early 2016 the company hosting the asset gems, ShellyCloud, had to shut the service down. After serveral months of community discussion it appears that project hosting is now provided by DigitalOcean and maintenance is supplied by Tenex.

If you find rails-assets to be valuable and are so compelled please go donate to the project.