AngularJS and Rails Tutorial: part 2 ng-boilerplate served by rails

Part 2 of a tutorial that connects AngularJS to a Rails backend. This post focuses on building the base angularjs application itself, which we’re going to create using the ng-boilerplate set of application scaffolding from joshdmiller.  The previous post was Building the rails app, the next post is Adding a list (query) to the AngularJS app.  You can also find the index of the posts in the tutorial, or hit the tutorials menu at the top and select the Rails 3 tutorial.  What we’re going to do is to insert our standalone angularjs application into our existing rails directory, but we’re going to manage our angularjs using the ng-boilerplate toolset, and our rails using the rails toolset. This should give us a page that looks pretty much like a standard ng-boilerplate demo page (albeit served from our rails server): Tutorial_2 vanilla ng-boilerplate The reason for this is that I want to use the latest version of all the angular tools, and I want to use the ng-boilerplate directory structure.  Whilst we can use rails to generate our code, and manage angularjs through the asset pipeline, in doing so I think we compromise our ability to use the best of the tools from the angularjs world.  In particular ng-boilerplate comes with a set of scripts that process and minify the javascript, and I don’t expect that to play well with the rails tools.

So, we’re going to aim to end up with our rails app living in app, test etc as it normally does, and our angularjs app living in src, build and other ng-boilerplate locations, all within the one directory structure. We’ll use rake and gemfiles to manage our rails app, and grunt and bower to manage our angularjs code.

The angular app will actually be served up by the rails web server for a variety of reasons to do with security and cross site scripting.  We’ll achieve that by linking the angular build directory into the rails public directory.

The rails app was created in the previous post, go back to that post and create it if you haven’t already, or pull it from the tutorial_1 branch on github.

The angular app we’re going to create by using the ng-boilerplate template provided by joshdmiller.  My aim here is to leverage the best of the angular ecosystem, and that means using the automated testing tools, the build tools and the pre-existing collateral.  Josh looks to have pulled a bunch of this collateral down into a single repository and made it (somewhat) easy to use, as well as having a directory structure that I think greatly improves modularity.

Before we do that we need to install nodejs, which provides the npm (node package manager) tool, which in turn we use to download everything else. In theory you can do this without installing nodejs, I haven’t quite worked that out yet, and it feels like AngularJS borrows some of the tooling from node, so easier to just install it.  On linux (in my case debian, which probably means ubuntu as well), we do this by installing the dependencies, then installing nodejs itself:

  • Install dependencies
      aptitude install python g++ make checkinstall
  • Make a directory in the source folder
      mkdir /usr/src/node
      cd /usr/src/node
      wget http://nodejs.org/dist/v0.10.15/node-v0.10.15.tar.gz
  • Unpack the code
      tar -xvf
      cd node-v0.10.15
  • Setup the installation
       ./configure
  • Build the code into an installation package
       checkinstall 0.10.15
  • checkinstall may fail, just running make directly in the directory may fix, then run checkinstall again
  • install the package
       dpkg -i node_0.10.15
  • We also install fontconfig, because we need it later
       aptitude install fontconfig

If you’re on OSX, you can do this by directly downloading a prebuilt package from the nodejs site.  I don’t recommend using brew, I tried that and had problems, the package worked fine. Having installed nodejs, we’ll clone the ng-boilerplate git repository.  We’re actually using git ourselves to version control our own app, so we don’t really want Josh’s repository to be our master.  We’re using some git trickery to get this effect, basically we want to pull the current state of ng-boilerplate without it becoming our master repository:

git remote add ngboilerplate git://github.com/joshdmiller/ng-boilerplate.git
git fetch ngboilerplate
git merge --squash ngboilerplate/v0.3.1-release
git commit -m "Merged boilerplate"

You’ll potentially get conflicts at the merge stage on the .gitignore file – if so edit that file to keep the superset of all changes, then execute the git commit -m. Next, we install the build and test tools

sudo npm -g install grunt-cli karma bower
npm install

Npm is the node package manager, so this is telling the node package manager to install stuff for us,  namely

  • grunt, which is the scripting tool (sort of like make in C++, or rake in ruby/rails).
  • karma, which is the test toolset, similar in concept to rspec in rails
  • bower, which is an installation tool, similar in concept to bundle in rails, with perhaps bits of the Gemfile thrown in
bower install

Bower is another installation tool, I haven’t yet worked out why we have both npm and bower, other than that I think that they are somehow complementary. Which isn’t a great answer. Finally

grunt build

This should build a base application for you. If, like me, you are running your development server headless (i.e. no UI and therefore no browser), this will give you an error that it cannot find Firefox. You can sort this by editing the browser setup at the bottom of karma/karma-unit.tpl.js.

    browsers: [
    ]

Run grunt build, which will hang waiting for a browser. Go to one of your browsers (Chrome is best) and visit http://localhost:9018. This will allow karma to capture your broswer. You can also use this approach if you want to test multiple browsers – so you can for example open Firefox and Chrome and visit that URL with both, and karma will then test every test on both of them. Now try running grunt build again:

grunt build

This will run the unit tests, and will concatenate and copy the code into the build directory on your filesystem. Try opening the application directly from the file system by entering something like the following into your browser:

file:///home/apps/league-tutorial/build/index.html#/home

Finally, we want to have this app served through our rails server, rather than opening from the file system. To do that we’re going to link our angular app into the public directory of the rails server, which will let the angular content be served directly. This makes sense because the angular app is similar in concept to the assets that get served from the public directory – it is mostly javascripts and templates, and the content should be largely static – i.e. the same for every user. We’re going to link the build directory to present as public/UI

cd public
ln -s ../build UI

We should now be able to get to our app from http://localhost:3000/UI/index.html Tutorial_2 vanilla ng-boilerplate The code at the ending point of this tutorial 2 can be found on github in the tutorial_2 branch. In the next segment of this tutorial we’re going to tie the two together – we’ll change our angular app to get data from the server for the club entity.

Advertisements

17 thoughts on “AngularJS and Rails Tutorial: part 2 ng-boilerplate served by rails

  1. Pingback: Rails app for Angularjs, building the rails league application: part 1 | technpol

  2. Pingback: CRUD application with AngularJS, Rails, twitter-bootstrap and ng-boilerplate: part 3 CRUD | technpol

  3. Pingback: CRUD application with AngularJS, Rails, twitter-bootstrap and ng-boilerplate: part 5 New and Delete | technpol

  4. Pingback: AngularJS and Rails: Tutorial Index | technpol

  5. I think that’s a Rails 4 issue, and I’ve seen comment on that before. I’m planning a Rails 4 upgrade soonish, at which point I’ll update the tutorial to match.

    In the meantime, I think the answer is to tell angular (Grunt) to use a different directory name than bin, so that it doesn’t conflict with rails

  6. Pingback: Installing ng-boilerplate, and serving it through rails | technpol

  7. If you’re on Rails 4, suggest looking at the RoR4 version of the tutorial. Boilerplate clobbers the bin directory of Rails4, so then Rails won’t run anymore. You need to change the gruntfile to tell boilerplate that you want the bin directory to be “angular_bin” instead of “bin”, which fixes that issue.

  8. Hey Paul – were trying to get this running on Heroku – any instructions on how to maybe get that going? Having issues with the symlink.

  9. Hey Owen,

    Unfortunately I have zero experience with Heroku, so I’m probably not a huge amount of help there.

    My initial thought would be to copy the build (or bin) folder into the public directory as a starting point – that should get you working. If that works for you, then your options for a more sustainable solution would be:
    1. Modify the ng-boilerplate/grunt build and bin directories to respectively be public/build and public/bin so that you don’t need the symlink
    2. Modify your rails setup so that it publishes the bin or build directories instead of (or as well as) the public directory.

    Off the top of my head I’d go for option 1, I seem to recall the relevant setting is in build.config.js.

    Good luck,

  10. Thanks Paul – were working through it using option 1.

    Only problem were facing is that were getting:
    ActionController::RoutingError (No route matches [GET] “/public/index.html”):

    But we never declared /public/ui and it worked when building locally? What would I have to update my routes.rb to get this new url to work?

  11. What we were doing was we put static content into the public directory, under public/UI. So we had a file /public/UI/index.html.

    We then visited that URL – so localhost://UI/index.html.

    It looks like you’re trying to go to localhost://index.html, not localhost://UI/index.html.

    If you want to avoid the UI prefix, then you would need to put the content directly into the public folder, not inside a UI folder. Alternatively, I suspect you can get rails to rewrite the URL for you, but I’m not 100% sure on how to do that, particularly in the Heroku context.

  12. Thanks Paul, should have said that I skipped adding the UI and just dumped everything into public. Close but I’ll have to do some more reading.

    Thanks for the help!

  13. Pingback: AngularJS and Rails CRUD application using ng-boilerplate and twitter bootstrap | Gatelockservice

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s