I had to learn this particular technology under fire, because I had basically hosed something in the production version of an application. This particular application has rather tight release controls, and as such we have a DEV, STAGE and PRODUCTION versions running at all time.
I have a tendency to want everyone around me to be able to write effective requirements documentation. I don’t necessarily know why I’m like this, but I use those skills constantly in an effort to more or less train people in how they think, write and talk.
I was working on something that I often use as a test development product when trying new tools and design paradigms. Basically, it's a story publishing system similar in nature to FictionPress.com or FanFiction.net. I like this, because it's a fairly complex scenario, but still within the realm of (what I see as) an understandable domain.
I like this as a problem space because it has complex structures. At its heart is a STORY, and this story would have attributes (such as title, author, category) and 1 to N CHAPTERS. While each chapter would have attributes (chapter title, content, etc) would have 0 to N COMMENTS.
This problem domain gives me nested data elements 3 levels deep, multiple avenues for data filtering and congestion, as well as users at various levels which would impact all of the data elements.
So, I started working on it in Ember, and was doing fairly well until I hit where I was building the route needed to view a specific story, a chapter at a time.
What I wanted to do here, was to use dynamic segments to control which story and chapter was displayed to the end user. Specifically, the route would be "/r/:story_id/:chapter_id." Now there are a few things to remember here.
The first is that while story_id is the actual identifier for the story to be read, chapter_id is not the chapter identifier, rather it would be the ordinal indicator for that chapter as a sequence within the overarching story. So, a route of /r/123/3 would be the third chapter of story id 123.
The second is that chapter_id needed to be optional. If I used the route of "/r/123" then I should have automatically been taken to the first chapter of story 123. Likewise any value outside of a number should also take you to the first chapter, while a numeric value larger than the highest ordinal chapter number should take you to the last chapter.
But most of that is a back end issue. It's the optional dynamic segment of :chapter_id that's we needed to focus on. After all, optional dynamic segments are a concept that just doesn't exist in Ember.
Worse, is that every example I saw, didn't allow for multiple levels of dynamic segments where the first of them is required and the second of them is dynamic.
So, I kicked at it, and created routes and configured them in a dozen different ways until I figured out how I could accomplish this.
What I did was built two routes.
The first I named "story" and the second I named "story-chapter." Then, instead of nesting the second option inside the first (which is how most of the examples performed something similar to what I was attempting, I entered two lines into the Router.map function found in router.js.
This configuration means that I have to routes for the "/r" root route, one which accepts the story_id dynamic segment, and the second which accepts the story_id and chapter_id dynamic segments.
Then in the story.js file, I used this to navigate from the story route to the story-chapter route.
Basically, this is the beforeModel function which processes before any data access on the request. Since we know that without a chapter_id dynamic segment, we're supposed to go to the first chapter, this takes the behavior of forcing you to that place.
Of course, in story-chapter.js, we can access the various dynamic segments in this fashion:
Now, I just need to get that commented aspect of things working the way I expect.