Software and Other Stuff


23 Jul 2013

Using AngularJS with a Rails backend

I created a sample AngularJS app which uses rails as a backend.

While it is possible to include AngularJS as part of the rails assets, I think it is better to setup the angular code base on a standalone folder, leaving the rails app as a (more or less) isolated backend.

There are several advantages to this setup:

Yeoman, Bower, Livereload and Karma Runner.

I want to stress out the convinience of working on your frontend using the stack yeoman sets up for you. By keeping the frontend isolated from the backend you get an amazingly fast development environment and draw a clear line between backend and frontend (great for making sure you are writing the right unit/integration tests). Yeoman sets up the test environment for you using jasmine as the testing library and karma as the runner. karma is possibly the fastest and most complete js test runner out there. And it is very well integrated with angular.


The experience of coding with Livereload is simply amazing. Immediate feedback for every little addition you save in your code editor while you are working, without having to reload the page in the browser!

True: you can use livereload with rails alone, and you can use bower with rails too. But Yeoman's angular generator sets everything right for you with a single command.

Rails was born in the request-response era of the web, and it shows. Yeoman sets up an environment with defaults that are better suited for developing web applications.

Setting the environment up

You'll need:

Shell session one: the rails backend:

rvm use 1.9.3
git clone https://github.com/EmmanuelOga/simple-angular-rails-app.git
cd simple-angular-rails-app
bundle install
bundle exec rake db:migrate
bundle exec rails s -p 3000

NOTE: the angular application was generated using these commands.

npm install -g yo generator-angular
mkdir ngapp; cd ngapp
yo angular notes

Shell session two: a grunt server

nvm use 0.10.13
cd simple-angular-rails-app/ngapp
npm install -g grunt-cli
npm install
bower install
grunt server # opens a browser window... you are done!

What's going on?

During development, you need to run both rails and the grunt server. The grunt server takes care of serving the assets (yes, it can serve coffeescript if you like that) and doing the live reloads.

We simulate that the whole environment is a single web application by running a proxy inside the grunt server. At some point during the production deploy process we'll be consolidating the whole angular app as a set of static assets in rails' public/ folder.

Here's a diagram of the stack during development:

Would it make sense to go the extra mile and just host the angular app and the rails backend as separated processes? It would. But this setup allows you deploy the whole thing as a single app in the end, and have everything in a single domain easily.

The grunt server task proxies any url with path /api to the rails backend on localhost:3000.

Would sinatra be a better choice for such a small app? It would... but the whole point of this blog post is to show a possible way of using angular and rails together. This setup should be usable if you already have a running rails app and you want to add some additional single-pagy parts to it.

TESTING

To run both the backend tests and front end tests, you can run:

rake test PHANTOMJS_BIN=`which phantomjs`

This is done by reopening rails's test task and adding a step to run the karma runner. This design is a bit simplistic but it works. You may want to have something a bit more elaborate to make it so angular's tests are run even if rails tests fail to complete.

The PHANTOMJS_BIN env var is needed because the project configures karma to use phantom js, but it could be changed to run any other browser.

karma can be configured to watch the tests as opposed to do a single run. You should deffinitively look into that during development.

Deploying

If you run grunt build, grunt will package the whole angular app in a tidy package on the rails public/ folder. This packaging step could happen in the server to avoid having to commit the generated assets in your repository, analogous to how it is done for generating assets with rails' assets pipeline.

XSRF support

The rails app sets the XSRF token in the cookies. The cookies are accessible even when using the proxy because the port is not taken into account when restricting access to the cookies.

Check ApplicationController for some notes on the XSRF protection.

Related Posts

28 Mar 2014
» Fun with Google's Apps Script! Batch Processing Gmail emails By Host
07 Oct 2013
» Graphs are Everywhere! An overview of GraphConnect San Francisco 2013
21 Apr 2012
» Tidying up an rspec suite with helpers


The opinions expressed in this personal blog represent my own and not those of my employer. All data and information provided is for informational purposes only. This blog makes no representations as to accuracy, completeness, currentness, suitability, or validity of any information on this site and will not be liable for any errors, omissions, or delays in this information or any losses, injuries, or damages arising from its display or use. All information is provided on an as-is basis.
adapt.960.gs  |  icons