There's a ton of documentation out there on how to build a brand new Ember.js app from the ground up, but not much documentation on how to migrate an existing Rails app to an Ember app. I'm going to share our experience with it, why we decided to migrate in the first place, and some pointers to make your migration a little easier if you wish to take your application to the next level.
Migrating GroupTalent from a good old fashioned, purebred Rails app to a shiny new Ember app has definitely been a challenge, but it was totally worth it for us in the end. Starting with such an early version of Ember was both a blessing and a curse. We had to do a lot of the heavy lifting ourselves at the start, including building ember-routemanager (before Ember had a router) and ember-layout (before Ember had outlets). And don't even get me started about the issues we've had with ember-data.
Doing a few years of Flex development in the past, Ember was immediately familiar by the way their bindings work and the ability to create modularized pages and controls. The ability to have modularized controls and "micro controllers" is really a game changer and allows you to think more like if you were building a desktop app. You can stop worrying about the server-side architecture that sometimes restrict you, and you can focus on more of a modular based architecture.
We began migrating our Rails app to Ember in February 2012, and we started with our sprint system. This seemed like a good place to introduce Ember into our app because our sprint system was a self-contained, isolated chunk of product. It made it easier to stitch Ember into our main Rails app. But it wasn't a cinch. We were still dealing with version 0.9.4 of Ember, and ember-data didn't even have versioning yet. Yes it was early. Very early. Documentation wasn't nearly as good as it is now.
To feed our Ember-infused sprint system with data, we started building a Rails API that ember-data communicated with. We began by only serializing the models we needed (sprint, sprint_item, match, etc.) and didn't even worry about serializing other complicated models like User (which is managed by Devise) until we needed them later on. Our models are serialized to the client using active_model_serializers and ember-data deserializes them on the other side.
Even though our sprints page was much more responsive and "app-like" than our older Rails pages, it wasn't until later when we ported over more of our pages and took advantage of the client side router that we really started seeing the benefits. Pages would load noticably faster than normal, and clicking through the site felt more like a desktop app than a web app. No more having to wait for the server to render your HTML.
If you're wanting to migrate your Rails app to Ember, here are the steps I would recommend taking:
- Get Ember.js and the required gems. Get the latest Ember.js, and install the ember-rails gem to help you with precompiling Handlebars. Also read through this great post for a more detailed explanation of getting started, with code examples.
- Choose a starting point in your app. A self-contained, modularized part of your app like our sprint system is probably a good choice. Something that doesn't have a lot of dependencies.
- Turn your Rails app into an API. We started by creating an '/api/' controller namespace and slowly started serializing more and more of our Rails models to the client as we needed them, until they were finally all serialized. Definitely use active_model_serializers to serialize your data down to the client.
- Decide on a data layer. We chose ember-data and dealed with a lot of issues. In fact, we're still dealing with issues and many of our bugs are ember-data related. If you have a lot of complicated relationships in your models, you probably shouldn't use ember-data. Instead, just use regular old ajax requests for sending and receiving data like Discourse and Square have used.
- Build up your client side router. As you start to convert pages of your Rails app to Ember, you'll be tearing out routes from routes.rb and replacing them in your Ember router. Eventually all that will be left in your routes.rb will be your API controllers.
Don't expect the migration to be a fast process. It's taken us about a year to fully migrate all of our pages over to Ember. Part of the reason it took so long was because we started with an alpha version of both Ember and ember-data. Both libraries have changed dramatically during this time and we've had to refactor our code serveral times to work with the newer versions.
But the latest Ember.js is rock solid and we definitely recommend using it. We now have 124 Ember controllers, 37 Ember models, 55 Ember routes, 92 views, over 200 handlebars templates and our Rails app is entirely stripped down to only an API.
Our site is faster, our code is cleaner, and personally it's super satisfying having a site that's built on a cutting edge client-side framework like Ember.js.
This is being discussed on Hacker News. Join in!
Care to discuss this article in your favorite forum? Vote on HN