blog

  • Home
  • blog
  • Setting Up an Angular SPA on Rails with Devise and Bootstrap

Setting Up an Angular SPA on Rails with Devise and Bootstrap

Setting Up an Angular SPA on Rails with Devise and Bootstrap

This article was originally published at jessenovotny.com.

When I started programming my very first Angular single page application (SPA), I noticed the resources for setup and integration with Devise to be thin or fragmented. The most useful guide I found was actually just a segment of a general Angular with Rails walkthrough. There were other resources that were either too complex or advanced, and they didn’t really go through the initial baby steps. One of the most daunting challenges for a new programmer is starting from scratch. I know, because I’m one of these folks.

Most of what I’ve learned through my online course has been delivered in small, increasingly more advanced components. I open a lab, and the groundwork is already laid out, so there isn’t a ton of practice in setting up an app from a blank slate. For the sake of course completion time, this makes sense. Besides, you only need to build a couple apps from the ground up to get a feel for how it’s done. If you haven’t gotten there yet, this walkthrough will be right up your alley.

Once I finally got all the pieces working and my first Angular project was up and running, I felt it pertinent to give back to the community. Since I currently don’t have enough “reputation points” to answer questions on Stack Overflow, the next best thing would be to make my own walkthrough for setting up an Angular SPA on Rails with Devise and Bootstrap. The following is exactly what I wish I had found in my initial research on the topic.

Granted, a huge part of web development is being able to solve complex problems without being handed the solution. I feel that sometimes a new developer just needs a helping hand. So here it is.

Getting Started

This guide is meant to be a diving board for getting started. It assumes you already have a basic understanding of Angular, Rails, Devise, and Bootstrap. I chose to not explore Active Record, but I do touch on Active Model Serializer, as it’s necessary for sending models to your JavaScript front end. There’s much more to learn about this subject and that would warrant its own series of guides. Likewise, I only go into installing Bootstrap to the point where I can verify it’s working.

Feel free to read along with the video I created for this tutorial:

Setting up

To get started, you want to open Terminal and navigate to the folder where you want to create your new application. In this demonstration, I’m on the Desktop.

In Terminal, you will run $ rails new YOUR-APP which initializes Rails, creates a directory with the entire framework, and bundles all of the baked in gems. (In case you’re unfamiliar, $ denotes a Terminal command.)

Open your Gemfile, remove gem 'turbolinks' and add the following:


gem 'bower-rails'
gem 'devise'
gem 'angular-rails-templates' #=> allows us to place our html views in the assets/javascript directory
gem 'active-model-serializer'
gem 'bootstrap-sass', '~> 3.3.6' #=> bootstrap also requires the 'sass-rails' gem, which should already be included in your gemfile

While Bower isn’t essential to this project, I chose to use it for one simple reason: experience. Sooner or later, I’ll probably find myself working on an app that was built with Bower, so why not start playing with it now?

What is Bower? You can learn more on their website, bower.io, but as far as I can tell, it’s essentially a package manager just like Ruby gems or npm. You can install it with npm, but I chose to include the bower-rails gem for this guide.

Initializing the Gems, Creating a Database and Adding a Migration

Now we’re going to install/initialize these gems, create our database, add a migration so users can sign up with a username, and then apply these migrations to our schema with the following commands:


$ bundle install
$ rake db:create #=> create database
$ rails g bower_rails:initialize json  #=> generates bower.json file for adding "dependencies"
$ rails g devise:install #=> generates config/initializers/devise.rb, user resources, user model, and user migration with a TON of default configurations for authentication
$ rails g migration AddUsernametoUsers username:string:uniq #=> generates, well, exactly what it says.
$ rake db:migrate

By the time you’ve got momentum building out your app, you’ll likely have many more dependencies or “packages”, but here’s what you’ll need to get started. Add the following vendor dependencies to bower.json:


...
"vendor": {
  "name": "bower-rails generated vendor assets",
  "dependencies": {
    "angular": "v1.5.8",
    "angular-ui-router": "latest",
    "angular-devise": "latest"
  }
}

Once you’ve saved those changes in bower.json, you’ll want to install those packages with the following command and then generate your user serializer from the ‘active-model-serializer’ gem installed earlier:


$ rake bower:install
$ rails g serializer user

Look for app/serializers/user_serializer.rb and add , :username directly after attributes :id so that when Devise requests the user’s information from Rails, you can display their chosen username. This is much nicer than saying “Welcome, jesse@email.com” or worse, “Welcome, 5UPer$3CREtP4SSword”. Just kidding, but seriously, don’t do that.

Add the following in config/application.rb directly under class Application < Rails::Application:


config.to_prepare do
  DeviseController.respond_to :html, :json
end

Since Angular will request information about the user using .json, we need to make sure the DeviseController will respond appropriately, which it doesn’t do by default.

Completing the Back-end Setup

We’re getting soooo close to finishing our back-end. Just a few more adjustments …

Open config/routes.rb and add the following line under devise_for :users: root 'application#index'. Then replace the contents of app/controllers/application_controller.rb with this whole snippet:


class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  before_action :configure_permitted_parameters, if: :devise_controller?
  skip_before_action :verify_authenticity_token

  respond_to :json

  def index
    render 'application/index'
  end

  protected

  def configure_permitted_parameters
    added_attrs = [:username, :email, :password, :password_confirmation, :remember_me]
    devise_parameter_sanitizer.permit :sign_up, keys: added_attrs
    devise_parameter_sanitizer.permit :account_update, keys: added_attrs
  end
end

We’ve done a few things here. First, we’re telling Rails that :json is our friend; our only view lives in views/application/index.html.erb; don’t worry about authenticity tokens when you get a call from Devise; oh, and our user will have a username.

Next open app/controllers/users_controller.rb and make sure you can access the user in JSON format with any /users/:id.json request:


class UsersController < ApplicationController
  def show
    user = User.find(params[:id])
    render json: user
  end  
end

Don’t worry about setting up the :show resource in routes.rb. Devise has done this for us already!

By default, Rails will initialize with views/layouts/application.html.erb, but we don’t want that (or rather, I don’t want this), so do the following:

  • Move that file to app/views/application/.
  • Rename it to index.html.erb.
  • Replace <%= yield %> with <ui-view></ui-view> (we won’t be rendering any erb aside from the script/style tags in our header).
  • Remove any mention of “turoblinks” in the script and stylesheet erb tags.
  • Add ng-app="myApp" as an attribute to the <body> tag. When we launch our server, Angular will load and frantically search our DOM for this before initializing our app.

The final step to getting our back end configured is laying out our asset pipeline. Bower has already installed a bunch of stuff for us in vendor/assets/bower_components. Likewise, we installed a bunch of sweet gems earlier. Let’s make sure our app can find these scripts and stylesheets:

Require the following in app/assets/javascript/application.js:


//= require jquery
//= require jquery_ujs
//= require angular
//= require angular-ui-router
//= require angular-devise
//= require angular-rails-templates
//= require bootstrap-sprockets
//= require_tree .

Note: don’t forget to remove require turbolinks

Finally, we must rename app/assets/stylesheets/application.css to application.scss and add these two @import lines at the end of our stylesheet:


*
 *= require_tree .
 *= require_self
 */
@import "bootstrap-sprockets";
@import "bootstrap";

Boom!! Now we have everything set up and we can start working on our front end.

Continue reading %Setting Up an Angular SPA on Rails with Devise and Bootstrap%

LEAVE A REPLY