Router with multiple dynamic segments in the url

Hello, Im quite new this kind of MVC, so I learned alot from Ember, but still I have a question, where I dont know if theres a solution in Ember.

I will try to show the problem with the excamples from the ember guides.

I have a router:

@resource 'posts', path: '/posts', ->
  @resource 'post', path: "/:post_id", ->
      @resource 'comments', path: "/comment"
          @resource 'comment', path: "/:comment_id", ->
              @route 'edit', path: "/edit"

With this I would have the URL: /posts/45/comment/3/edit

Is this even possible? How would I refer to it?

"posts.post.comments.comment.edit"

And how would the controllers be named?

PostsPostCommentsCommentController? And what about the comment id’s? Can they have the same id like:

/posts/222/comment/3/edit 
/posts/45/comment/3/edit

or does any comment have a unique id?

I really would like to have it RESTful, especially as I am learning to work that way. I tried around abit, but it doesnt seem to work.

I hope you guys can give me some help on how to work with this.

Regards Gerrit Sommer

1 Like

In this case, those routes would create:

  • PostsRoute
  • PostRoute
  • CommentsRoute
  • CommentRoute
  • CommentEditRoute

So you would refer to your comment edit route as just

comment.edit

Route names only take one resource, followed by it’s routes (I think).

In addition to @chrisb’s reply check out the defining your routes guide (Defining Your Routes - Routing - Ember Guides) which has a near identical example matching yours.

1 Like

hmm, so I guess its possible. so what if I want to make a “linkTo” to the post 23 with all the comments listed and in the edit-view of one comment?

{{#linkTo posts.post.comments.comment.edit comment}}edit comment{{/linkTo}}

And I would end up at at this view, if I would make my templates properly with some outlets etc. :

—> sorry, new users arent allowed to publish images, so heres my dropbox link: https://dl.dropboxusercontent.com/u/149014004/ember.png

I still feel I’ve got a design error in my router definition. I can only give the comment to the linkTo helper, but not the post object. How would Ember know I want to view the post with the id 23 and its comments and one comment with the id 4 in the edit view.

EDIT: Ok, I think I got a functional version of this, where everything seems to run well. I will post how the controllers, templates etc. work and how to set the content, when I’ve finished and sure its working the Ember way :wink:

I think you would just do:

{{#linkTo comment.edit this}}Edit Comment{{/linkTo}}
//assuming you were iterating through the comments

@chrisb is right, the dotted route path (comment.edit) is at most two parts: the route (verb), preceded by parent resource (noun), if it has one.

The unspoken rule with Ember’s router, I believe, is that all routes must be uniquely named or be nested within a uniquely-named resource.

Ember won’t throw any errors if you define duplicate routes, but the higher-level routes will take precedence over nested routes:

@resource 'posts', path: '/posts', ->
  @resource 'post', path: "/:post_id", ->
    @resource 'comments', path: "/comment" ->
      @resource 'comment', path: "/:comment_id", ->
        @route 'edit', path: "/edit"

// These routes will take precedence over the nested routes above. 
@resource 'comments' ->
  @resource 'comment', path: ':comment_id'
1 Like

If you did want to have both the top-level comments route and nested post-comments, you’d do something like this:

App.Router.map ->
  @resource 'posts', path: '/posts', ->
    @resource 'post', path: "/:post_id", ->
      @resource 'postComments', path: "/comments" ->
        @resource 'postComment', path: "/:comment_id", ->
          @route 'edit', path: "/edit"

  @resource 'comments' ->
    @resource 'comment', path: ':comment_id'

App.PostCommentsRoute = Ember.Route.extend

App.PostCommentRoute = Ember.Route.extend

App.PostCommentEditRoute = Ember.Route.extend

The trick is to remember that a route has no knowledge of its own nesting beyond inheriting part of its name from its parent resource.