One to many relationship not displaying on detail page

Hi,

Rather having a master-detail view, whereby you might have a list of posts in the left hand column and the post detail to right, I have the posts and post detail on separate pages using this router

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

In my post route I have

export default Ember.Route.extend({  
  model(params) {    
      return this.store.findRecord('post',params.id) 
}});

The post model has a one to many relationship with comments (and other relationships which I’ve omitted here)

 export default DS.Model.extend({   
    name:DS.attr('string'),    
    description:DS.attr('string'),    
    comments:DS.hasMany('comment')
   });

I am sure my API is returning the correct response on /posts/1 for example - here is a sample

{"data":{"id":"1","type":"posts","links":{"self":"/api/posts/1"},"attributes":{"name":"Post 1","description":"post   text"},"relationships":{"comments":{"links":{"self":"/api/posts/1/relationships/comments","related":"/api/posts/1/comments"}}}}}

and here is the response on /posts/1/comments

{"data":[{"id":"1","type":"comments","links":{"self":"/api/comments/1"},"attributes":{"description":"comment for post 1"},"relationships":{"post":{"links":{"self":"/api/comments/1/relationships/post","related":"/api/comments/1/post"}}}},{"id":"2","type":"comments","links":{"self":"/api/comments/2"},"attributes":{"description":"another comment for post 1"},"relationships":{"post":{"links":{"self":"/api/comments/2/relationships/post","related":"/api/comments/2/post"}}}}]}

The problem is this … on the post detail page I want to list the comments relating to the post. eg

 {{#each model.comments as |comment|}}<p>{{comment.description}}</p>{{/each}}

If I am viewing the post detail page and refresh, the comments show. If I go to the post page from /posts though - they don’t show, they only do if I refresh the page again.

On the posts template I have tried passing the model and just the model id but neither makes any difference:

{{#each model as |post|}}
{{link-to post.name 'post' post.id}} //  {{link-to post.name 'post' post}}
{{/each}}

Many thanks in advance!

Hey @therealbenhogan,

I replicated your app as closely as possible and couldn’t reproduce your issue:

Which versions of Ember/Data/CLI are you using? Would you mind trying that one (git clone, npm install, bower install, ember server) and spot the differences?

I once heard of someone having a similar problem when using http-mocks, are you using that too? What serves your API?

Hi,

Many thanks for getting back - the API is served by the Slim Framework in PHP … I am going to try using Mirage to double check the API response first I think - will report back! If there was a problem with the API would that explain why you can see the related comments if you refresh the page, but not if you use the link-to helper?

Hi Frank,

Many thanks for this - Iet me have a look at your app - I’ll report back on the differences!

1 Like

Hi Frank,

I’ve run your code and all working perfectly.

My code was running ember-cli 1.13.15 versus 2.3.0 (!)

ember 2.2.0 versus 2.3.1

ember-data 2.2.0 versus 2.3.0

There are a bunch of other differences in the package.json and bower.json files too - did you generate your app directly from ember-cli and then have to make adjustments? At the moment, I’ve got some npm errors I need to look into into but I wanted to get back with the main differences

Yeah, I generated the app with Ember CLI 2.3.0. No adjustments whatsoever, I first installed Mirage but then commented out.

Hi,

I ran a fresh install of ember-cli and generated a new app with my backend … and it worked …

Not too frustrating then! Many thanks for your help - really appreciate it !!

I know this thread is a little old, but I’ve also been running into trouble with one-to-many relationships not being populated and this feels similar to my issue.

For example a post has comments but only the ids of the comments are retrieved but the rest of the comment model’s fields are not retrieved or connected.

Is the solution to have an RSVP in the application route get all the posts and comments

model() {
  return RSVP.hash({
    posts: $.getJSON('/api/posts'),
    post2: $.getJSON('/api/posts/2'),
    commentsFor1: $.getJSON('/api/posts/1/comments'),
    commentsFor5: $.getJSON('/api/posts/5/comments')
  });
}

Similar to @emberigniter’s example code above.

Also in the example, it looks like mirage has a special route for post comments:

this.get('/posts/:id/comments', function(schema, request) {
    const postId = request.params.id;
    return schema.comment.where({ postId: postId });
});

I am using the JSONAPI format for the API data and mirage for development purposes.

Using this as an example: I’m trying to figure out the best way to handle one-to-many relationships in terms of having the data available for all the comments associated with a specific post (so more than just an ID but the actual fields in a comment) available in the post template. How do you get ember to “hydrate” that data properly and consistently?

I’m using a later version of ember-cli (2.9.0).

Any suggestions or advice would be appreciated.

@jas Not that code, please!

In general I think RSVP.hash should be avoided, and in that particular case it really was a “hack” in the context of the article (evidenced by the use of $.getJSON) to show Mirage was working correctly.

Seeing only ids is a tell-tale sign of Ember Data promise objects that haven’t resolved. I strongly recommend you read my article on promises and computed properties: https://emberigniter.com/guide-promises-computed-properties/

After that I promise you will understand what is going on with your code.

Hey @emberigniter thanks for the response.

Yeah, I figured the $.getJSON was just setup for the means of answering the original question but thought maybe the RSVP.hash was the method I should be looking at.

I guess I wasn’t sure if I was using Mirage the wrong way.

Thanks for the link to your article. It does look promising ( :slight_smile: ). I will take it for a test drive soon.