originally posted on the Intridea blog here: http://www.intridea.com/blog/2014/10/14/how-to-set-up-angular-with-rails-part-2
In Part I of our Angular series, we illustrated the process for setting up an Angular app for Rails.
In Part 2 of this series, we'll be creating a basic HR app. This app will allow us to view employee information through an Angular app (edits and updates to be explained in Part 3 of this series). For more details, see code in Github link at the end of post.
Here's a quick snapshot of what we'll be creating for our HR app:
- Setting up test frameworks
- Creating a Rails API
- Making the Angular frontend talk to the Rails API
Setup RSpec
First, remove the test/
directory. This is left over from our initial app setup in Part 1: How to Set Up Angular with Rails. Then add RSpec and factory_girl_rails to the Gemfile:
Next, bundle and install it.
And edit your spec/spec_helper.rb to match:
Create the Employee Model
Let's create the Employee model with a few fields:
Next, we'll add some validations in app/models/employee.rb:
Before creating the API interface for Angular, let's create a serializer for our Employee model. This will allow our API to expose only those fields that are necessary to Angular frontend. Add ActiveModel Serializers to the Gemfile
And bundle install
Create the Employee API
In order to support the Angular frontend, we'll need to create an API controller at app/controllers/api/employees_controller.rb:
Now we need to define that EmployeeSerializer in app/serializers/employee_serializer.rb:
And expose this API to the frontend in config/routes.rb:
Finally we'll add some Employee data to db/seeds.rb:
Seed the database and start the Rails server:
Then we can open http://localhost:3000/api/employees in the browser which will return:
Test the API
Now that we've verified this action is set-up correctly, let's add a factory at spec/factories/employees.rb:
Next, add a test at spec/controllers/api/employees_controller_spec.rb:
While the above test is somewhat trivial, this set up is great for verifying more complex logic in real world applications. In addition, the reason for adding an API spec prior to the Angular portion is to avoid playing the guessing game if/when problems arise; waiting to add the Angular framework helps to ease the deciphering process. If your Angular app isn't working correctly, its important to verify that the Rails backend is also behaving correctly -- the problem may not be an Angular issue.
Create the Angular frontend
You may want to take a look back at Part 1: How to Set Up Angular with Rails to review how we setup the AngularJS frontend with Rails. Let's start by defining an app in app/assets/javascripts/angular-app/modules/employee.js.coffee.erb:
Next, we'll define the Employees controller in app/controllers/employees.rb:
Then, we'll add to the beginning of config/routes.rb:
Finally, let's start the Angular app in app/views/employees/index.html.erb:
If you run the Rails server and hit http://localhost:3000/ you'll get an error about the controller not being defined yet in the javascript console. Before we create the controller, let's setup a Employee model and service to handle fetching Employee records from the Rails API.
The Employee model is defined at app/assets/javascripts/angular-app/models/employee/Employee.js.coffee:
There is no special behavior here yet. It is only returning the data that comes from the API.
To ease the process of working with APIs in Angular, let's add the restangular library to our project. In bower.json add restangular:
Then run bundle exec rake bower:install
. Next, we need to add restangular and its dependency lodash to app/assets/javascripts/application.js:
Afterwards, we'll create the Employee service at app/assets/javascripts/angular-app/services/employee/EmployeeService.js.coffee:
Finally, let's create the controller at app/assets/javascripts/angular-app/controllers/employee/EmployeeListCtrl.js.coffee:
If you run the Rails server and visit http://localhost:3000/ in the javascript console you'll see a print out of the Employee objects previously seeded to the database. Next, let's add to the template code to show our Employee objects. In app/views/employees/index.html.erb:
Open http://localhost:3000 and notice the salary field. We used the currency filter to handle formatting that data. Salary comes back from the API as a plain integer value. Angular has a number of useful filters that are included by default.
The above example is very basic. However, we created database objects, exposed those via an API, tested the API, and created an Angular app to handle the frontend. That's no small task! A few pieces are still missing though. While our Ruby API has tests, our Angular app has no tests at all. Furthermore, our employee management app is view-only.
Github code for HR app here.
In Part 3, we'll setup javascript tests, and add editing functionality to our Angular frontend.