Remus Rusanu
Remus Rusanu

Reputation: 294487

Proper Ember.js resource route declaration

I'm trying to wrap my head around Ember resources but I'm hitting a wall. Looking at guides like Rails + Ember.js I see the preffered way of declaring a resource route is:

EmberTester.Router.map(function() {
  this.resource('posts', function() {
    this.resource('post', { path: ':post_id' });
  });
}); 

This seems very convoluted, having to create a nested resource to access the individual items. But besides the element of style, the real problem is the behavior: such a route, from what I can see in the serverside log and in the client side browser traffic monitoring evaluates the model hooks for both the 'posts' route and the 'post' route. That is, given the model hooks:

EmberTester.PostsRoute = Ember.Route.extend({
  model: function() {
    return EmberTester.Post.find();
  }
});

EmberTester.PostRoute = Ember.Route.extend({
  model: function(params) {
    return EmberTester.Post.find(params.post_id);
  }
});

when visiting the url /posts/1 both model hooks get executed, so the server is first asked for all posts and then for post_id:1. I must be missing the obvious, but I can't put my finger on it what is it.

Is there a simpler way to declare resources in Ember? Should I not declare resources and instead use plain routes?

Upvotes: 3

Views: 738

Answers (2)

Gevious
Gevious

Reputation: 3252

The nesting in the router translates to nesting in your whole stack. If you like to have a list of posts on the left, then edit an individual post on the right hand side of your screen (as per the Ember Guide), then nesting will work for you. If you don't need that kind of behaviour you don't need to nest your routes at all. Nesting is perhaps more useful if you need related information like /posts/comments/ where you'd never find comments without some kind of post.

Also note, you should probably declare the Router as follows if you're not nesting:

App.Router.map(function () {
  this.route('posts');
  this.route('post', { path: '/posts/:post_id' }); 
});

Upvotes: 1

Alex Navasardyan
Alex Navasardyan

Reputation: 536

I created a jsbin to reproduce the issue you're talking about and changed the router code a bit:

App.Router.map(function () {
  this.resource('posts');
  this.resource('post', { path: '/posts/:post_id' }); 
});

It does exactly the same thing as nested routes (I think, under the hood post is treated is nested).

When you navigate to PostsRoute, model hook of PostsRoute is fired. If you click on specific post, PostRoute model hook is not going to be fired.

However, if you go to a specific post and refresh the page, you'll notice that this time PostRoute model hook is fired.

You should use treat nouns as resources (posts, post, orders, etc) and verbs (adjectives) as routes (new, show, edit, etc.).

Hope this helps.

Upvotes: 2

Related Questions