I explored two approaches for integration and both have their own pros and cons:
This approach is suitable if only a part of the Rails application views need to be migrated into Angular with minimal changes in the deployment process.
1. Update GemFile with the following gems and install them:
2. Install Bower:
rails g bower_rails:initialize
3. Add all desired dependencies in Bowerfile
4. Install dependencies by rake task bundle:
exec rake bower:install
5. Add the Angular project skeleton
This approach is the best choice if the plan is to migrate all existing Rails views to AngularJS. Rails applications used for serving the API and Angular app will work as an API client. When we gradually start moving existing Rails views to the Angular app, then we want to keep a single deployment of the application in two cases:
1. Create a ‘client’ folder parallel to the Rails ‘app’ folder and setup the Angular app directory structure similarly to what we discussed in first approach.
2. Add all required NodeJS packages in package.json and install those packages.
3. Add the required library, framework, and assets packages in bower.json and install Bower dependencies.
4. Remove the content from the Rails’ public folder; this folder content will be replaced by the output of the Grunt build.
5. There can be many ways to organize assets in a public folder: either all Grunt-generated assets can be added directly to the public folder or a specific app folder can be created in the public folder, which contains all Grunt-generated assets.
6. Change the line dist: ‘dist’ to dist: ‘../public’ under the var appConfig section of client/Gruntfile.js.
7. Add the public directory to .gitignore to remove it from version control.
8. In development environment, Grunt build can be executed manually but in production this process has to be automated.
There are two approaches for deploying this kind of Rails application. We can either run Grunt locally and upload the public folder to a remote server or run the Grunt build on a remote server. With the former approach, the installation of Node and Grunt on a remote server can be easily avoided. I would prefer the former approach of building locally and copying to remote because that can be written in a custom Capistrano deployment task.
If the deployment is on Heroku, we can leverage multiple buildpacks, with each buildpack handling Rails and Angular deployment separately. This article can be useful for setting up buildpacks.
You need to determine which approach is suitable for you. Our advice is that if you are building an application for the long haul, you should take the standalone setup to leverage the best of both frameworks. This also keeps your options open to move to a micro-services architecture if the need arises in the future.