Nesting routes instead of resources with ember.js

Published on December 04, 2014 by Toran Billups

I've been building ember.js web apps with ES6 for so long now that I almost forgot how to do it with pure globals. Just the other day I was looking at an older ember.js app and remembered one of the pain points surrounding nested routes pre ES6 modules. If you wanted your templates/routes/controllers/views to match the url you would do so with the understanding that your global object names would also be nested.

As you can imagine, these object names got verbose very quickly. So instead most people would skip the true nesting concept and use resources instead. This had the wonderful side effect of less verbose object names, but came at the cost of a flat file system that didn't mirror the nested url structure.

For example, the router defined below would yield a set of routes ...

AccountsRoute

DetailRoute

UsersRoute

And if we take a look at the templates folder you will see that each file is a "top-level" resource even when the router had several nested urls defined.

If you prefer the templates/routes/controllers/views are instead nested, you would update the router to look like the below.

But now that we have truly nested routes those route object names are suddenly more complex.

AccountsRoute

AccountsDetailRoute

AccountsDetailUsersRoute

Lucky for us, in the modern ember.js ecosystem you simply don't feel the pain you did with globals because you no longer need to actually type out the full name. In fact, you can skip naming your objects altogether and just do an "export default" saving yourself all that typing. In addition, your templates/routes/controllers/views will reflect the same nesting that you defined in the router!

The entire project is up on github with my typical "before and after" commit style so you can see exactly what was required to switch from nested resources to nested routes

note: in the example project I still named the routes using the verbose names but that name is not required and could be anything -the resolver will still pick it up correctly. I do this to help me navigate around my projects in vim with ctags.