I’d say it should be inferred of the context too. I have some resources that I have multiple way to access it. For instance, I could access all the messages of a user user /users/2/messages, but I could also access all messages using /messages (for admin purpose, for instance).
App.Message = DS.Model.extend({
content: DS.attr('string')
});
App.Conversation = DS.Model.extend({
messages: DS.hasMany('message', {allowNesting: true});
});
this.store.find('message'); // GET /messages
this.store.find('conversation', 1).get('messages'); // GET /conversations/1/messages
// This would trigger two requests, so many it's better to allow a notation like that:
this.store.find('conversation.messages', 1); // GET /conversations/1/messages
(If allowNesting is set to false - which should be the case by default -), then accessing the /messages would always hit the root URL).
It should be smart enough to make some assumption, so if we are currently in a route that have :conversation_id parameter, and that we have a nested MessageRoute, a call to “this.store.find()” should do it based on the context (so a conversation):
App.ConversationMessageRoute = Ember.Route.extend({
model: function() {
return this.store.find('message'); // Hit /conversations/:conversation_id/messages
}
});
But this should be easily overridable, for instance using some kind of options to the “find” method that would force to access the resource using its base URL:
return this.store.find('message', {forceRoot: true}); // Will hit "/messages"
Now, something important is trying to avoid too deeply nested URL. This is an often done error in REST design to have very deeply URL. For instance, “/users/5/tweets” is a good idea, but “/users/5/tweets/6/retweets” is definitely not a good idea and should be rewritten “/tweets/6/retweets”. I’d suggest limiting the nesting to one level, and always “drop” parts of the URL to avoid a too nested structure. OR we allow to configure that per nested resource:
App.User = DS.Model.extend({
tweets: DS.hasMany('tweets', {allowNesting: true, maxNestingDepth: 2})
});
App.Tweet = DS.Model.extend({
retweets: DS.hasMany('tweets')
});
EDIT: another idea would be to introduce a findAssociation method:
this.store.findAssociation('messages', 'conversation', {post_id: 43}}; // post_id could be infer from routes parameters