Child route not hitting rails


#1

Hi All,

I am trying to render Issue’s children. Ember route changed in browser URL, but it didn’t hit the Rails API.

My URL looks like this: /issues/:id/issues

Show.hbs File

{{#link-to “issues.show.issues” model.id}} {{#tablist.tab “TabB” on-click=(action (mut selection))}} {{/tablist.tab}} {{/link-to}}

router.js

this.route(‘issues’, function() { this.route(‘index’, { path: ‘/’ }); this.route(‘show’, { path: ‘/:issueId’ }, function(){ this.route(‘issues’); }); });

routes/issues/show/issues.js

import BaseRoute from ‘…/…/base-route’;

export default BaseRoute.extend({ model(params) { let issue = this.modelFor(‘issues/issue’, params.issueId); return issue.get(‘issues’); } });

No errors found in frontend and backend.

Ember version: ember-cli: 2.12.1

Appreciate your inputs here.

Thanks.


#2

Hi @Chitra, there could be a couple things going on here. The first thing I noticed is your model hook in routes/issues/show/issues.js. Are you sure the this.modelFor call is returning anything? I think the syntax you’d want there is let issue = this.modelFor('issues.show', params.issueId).

One way you can verify this is putting a breakpoint in the model hook on this line: return issue.get('issues'); and making sure that the ‘issue’ variable has a value.

If that’s not the issue, could you post the route for routes/issues/show.js and maybe your model definitions too?

EDIT: think of issues.show as the route’s “name”. And issues/issue/:issue_id as the route’s “path”. In Ember you pretty much always reference a route by it’s name and never by it’s path. That applies to the link-to helper, the modelFor method, and most other places where you’d reference a route.


#3

Thanks @dknutsen , I already tried this > this.modelFor(‘issues.show’, params.issueId). but it didnt work.

Will continue debugging model.

Here is the routes/issues/show.js

import BaseRoute from ‘…/base-route’;

export default BaseRoute.extend({ model(params) { return this.store.find(‘issue’, params.issueId); } });

JSON API data : http://localhost:3000/SEARCH/issues/51/issues.json

{ “issues”: [ { “id”: 59, “title”: “Consequuntur qui optio similique maiores fugit.”, “issue_type_id”: 3, }, { “id”: 68, “title”: “Consequuntur qui optio similique maiores fugit.”, “issue_type_id”: 3, } ]}

Issue.rb

import Ember from ‘ember’; import { memberAction } from ‘ember-api-actions’;

export default Model.extend({ key: attr(‘string’), title: attr(‘string’),

// Associations transitions: hasMany(‘transition’, { async: false }), children: hasMany(‘issue’, { async: false, inverse: ‘parent’ }),

transit: memberAction({ path: ‘/’ }) });


#4

I think I see what might be going on. In your route you’ve got this:

// routes/issues/show/issues.js
import BaseRoute from '../../base-route';

export default BaseRoute.extend({
  model(params) {
    let issue = this.modelFor('issues.show', params.issueId);
    return issue.get('issues');
  }
});

So what this is doing is getting the parent route’s model, which is a single instance of an Ember Data ‘issue’ model. Then you’re returning issue.get('issues'), which you’d think would work fine except for two things:

  1. it doesn’t look like you have any attribute/relationship on your ‘issue’ model called ‘issues’. I think the one that you want is ‘children’ (eg. issue.get('children').
  2. Even if you changed it from issue.get('issues') to issue.get('children'), you’ve never fetched the children, and you have the async:false flag on your relationship so it will never fetch them.

I’m going to go out on a limb here, so sorry if I’m totally off base, but I think you may be trying to conceptualize your Ember routes as matching your Rails routes too closely. Ember routes and Rails routes don’t really have much to do with each other, other than they might have a similar structure. Ember Data is the interface between your Ember app and your Rails backend, so no matter how you set up your Ember Router, it won’t change the URL that Ember requests data from, meaning if you’re trying to fetch the child issues from the URL http://localhost:3000/SEARCH/issues/51/issues.json you’re probably either going to need to do some Ember Data customization or modify your API or how you’re using your API.

Anyway, I think the problem is that in your issues/show/issues route you aren’t actually returning anything in the model hook (for the two reasons I described above).

I would try changing your route to something like this:

// routes/issues/show/issues.js
import BaseRoute from '../../base-route';

export default BaseRoute.extend({
  model(params) {
    let issue = this.modelFor('issues.show', params.issueId);
    return issue.get('children');
  }
});

And then change the children relationship to async: true so when you do issue.get('children') it will fetch the data the child issues. Of course it’s still not going to fetch them from http://localhost:3000/SEARCH/issues/51/issues.json… it would probably try to do multiple requests like: http://localhost:3000/SEARCH/issues/<child-1-id> http://localhost:3000/SEARCH/issues/<child-2-id> http://localhost:3000/SEARCH/issues/<child-3-id> etc…


#5

Yes, it did the trick! I’ve changed the issue.js file and > async: true . Moreover I’ve added the link mapping to children in serializer. Now I can achieve it in a single request.

Thanks a ton!


#6

Awesome! Glad you got it working.