Skip to content

Instantly share code, notes, and snippets.

@commadelimited
Created October 1, 2013 14:55
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save commadelimited/6779774 to your computer and use it in GitHub Desktop.
Save commadelimited/6779774 to your computer and use it in GitHub Desktop.
Nested URLs
I'm trying to consume an endpoint from my server to retrieve interactions.
This interaction is restricted by account and can only be accessed once you're within the account route.
URLs
----
/activity/#/accounts/64/ <-- loads account information
/activity/#/accounts/64/interactions <-- I want to load interactions here
Ember is making a call to the interactions endpoint, but it's hitting the wrong path:
API
---
/api/1/interactions/ <-- what Ember is hitting
/api/1/accounts/64/interactions/ <-- what Ember should be hitting
Is there something I can do to alter the endpoint that Ember is trying to hit? Below are the details on my stack:
DEBUG: Ember.VERSION : 1.0.0-rc.8
DEBUG: Ember.Data.VERSION : r13
DEBUG: Handlebars.VERSION : 1.0.0
DEBUG: jQuery.VERSION : 2.0.3
Social.Router.map(function() {
this.resource('accounts', { path: '/accounts' }, function(){
this.resource('account', { path: ':account_id'}, function(){
this.resource('interactions', { path: 'interactions'});
});
});
});
@mehulkar
Copy link

mehulkar commented Oct 1, 2013

Try this:

Social.Router.map(function() {
    this.resource('accounts',  { path: '/accounts' }, function(){
        this.resource('accounts.account', { path: ':account_id'}, function(){
            this.resource('accounts.account.interactions', { path: 'interactions'});
        });
    });
});

@commadelimited
Copy link
Author

Looks like changing that would require me to go through and make changes to templates, Routes and Controllers. I was either doing something wrong, or had the wrong combination as I couldn't get this working.

@mehulkar
Copy link

mehulkar commented Oct 1, 2013

Yeah, naming is a big deal in Ember unfortunately :/. resources don't nest nicely unless you specify the hierarchy.

@swinton
Copy link

swinton commented Oct 3, 2013

A random late night thought. Should interactions be a route off account, rather than a resource? If I remember correctly, resources can have multiple routes (so /accounts/1/index/, /accounts/1/delete/, /accounts/1/interactions/ etc.) but the index route is implicit.

So...

Social.Router.map(function() {
    this.resource('accounts',  { path: '/accounts' }, function(){
        this.resource('account', { path: ':account_id'}, function(){
            this.route('interactions', { path: 'interactions'});
        });
    });
});

Worth a shot?

@commadelimited
Copy link
Author

So there might be a potential bug with this. I just realized that I'm using a linkTo helper like this:

<li class="view-interactions" title="Interactions">{{#linkTo "interactions"}}Interactions{{/linkTo}}</li>

And it links to the correct route, with the account id specified in the URL as expected. The problem is that the Ember Data call is pointing to the wrong API endpoint.

@kylenathan
Copy link

Thats all correct - API endpoints are independent of your routes. ED will by default hit the endpoint api/model_name/:id

You can configure an API endpoint like your example by using '_links' in the payload.

More info at (but not sure whats available in R13, you'll need to do some digging) :-

http://jsonapi.org/format/#url-based-json-api
https://github.com/emberjs/data/blob/master/TRANSITION.md
https://github.com/emberjs/data/search?q=links&type=Code

@commadelimited
Copy link
Author

@kylenathan, do you have more information about this "'_links' in the payload" you mentioned?

@ryanflorence
Copy link

I'm not sure why everybody is posting application routes, because they are not the routes your models are going to use.

In new ED beta 1.0 you get per model adapters/serializers. So it'd look something like this:

App.Interaction = DS.Model.extend();

App.Account = DS.Model.extend({
  interactions: DS.hasMany('interaction', {async: true})
});

App.AccountSerializer = DS.RESTSerializer.extend({
  normalize: function(type, hash, property) {
    // want to construct a url like this:
    // /api/1/accounts/64/interactions
    var base = '/api/1/accounts/'+hash.id;
    hash.links = {
      // if your server doesn't send this links key, we can do it
      // ourselves and shove it back into ED
      interactions: base+'/interactions'
    };
    return this._super(type, hash, property);
  }
});

App.InteractionsRoute = Ember.Route.extend({
  model: function() {
    // since your interactions route is nested in `account`, we just
    // ask for the relationship, when it lands, the data will populate
    return this.modelFor('account').get('interactions');
  }
});

@commadelimited
Copy link
Author

Ryan, that's the question I have. How do I tell the Model where to look for it's data? Is that possible in r13?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment