In one of my projects, we were tasked to put AngularJS on top of an existing Rails app. We wanted to keep the business impact at a minimum. This means that we had to gradually make the transition while adding more end-user features.
Since retro fitting a client side framework is pretty common for many Rails apps, I’m going to share some of the problems I’ve encoutered, and possible approaches I used.
HAML or HTML?
We ended up created a
TemplatesController and route all of the template fetching requests though this
TemplatesController. From browser’s perspective, we are still serving static HTML, but we were able to write it in HAML from the server side.
1 2 3 4 5 6 7
1 2 3
One added benefit was that because we are still on the server side, we have access to things like
I18n.t 'store.title', which we otherwise have to duplicate at the client side.
Do we have to write validations twice?
I really like the ActiveRecord error messages. It has good defaults, easily configurable, and intergate well with i18n. At the same time, I want the good user experience that’s provided by the client-side validation. Refreshing the page to see errors is so 2008.
I also don’t want to write our validations and messages twice. The server side already has validations, we just need to pipe the error messages out to the page via ajax. Its easy with AngualrJS
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8 9
Note: The approach works for us becuase our application only validates the input after the user attempts to submit the form. It might not work well in your case.
Turn functions into services
We use CanCan for access control. In the view, we show and hide certain elements depending on the current user’s role. The code snippet below hides the Edit button if
current_user does not have the
Since we are switching to client side templates, we don’t have direct access to
ability object anymore, but we can turn the CanCan ability into a service call. A get request to
/abilities.json will return something like this for the current user:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
In the view, we can choose to show/hide elements based on the user’s role again.
1 2 3 4 5