Ska
Ska

Reputation: 6888

Ember model: one to many fixtures, server calls

Looking at the guide on Ember page, I can't figure out how to wire models in one to many relatinship.

App.Post = DS.Model.extend({
  comments: DS.hasMany('comment')
});

App.Comment = DS.Model.extend({
  post: DS.belongsTo('post')
});

1. How to define fixtures? A or B or something else

A) Comments in every Post 'object'

App.Post.FIXTURES = [
{
  id:1,
  title:"hello world",
  body:"hey ho",
  comments:[
   {
    text: "Very nice"
   },
   {
    text: "Very nice indeed"
   },
  ]
},
{
  id:2,
  title:"hello again",
  body:"I'm Bob",
  comments:[{
   text: "Pretty cool actually"
  }]
}
]

B) Comments separately and linked with id's to Posts

App.Post.FIXTURES = [
{
  id:1,
  title:"hello world",
  body:"hey ho"
},
{
  id:2,
  title:"hello again",
  body:"I'm Bob"
}
]

App.Comment.FIXTURES = [
{
  post_id:1,
  text: "Very nice"
},
{
  post_id:1,
  text: "Very nice indeed"
},
{
  post_id:2,
  text: "Pretty cool actually"
}
]

2. About fetching from server

A) Do I need to load Posts separately and Comments separately, or all in one call, having them structured like in the 1A case?

B) What if I want to lad them separately, for example waiting for user to click ok comments link, no need to download 1000's of comments for every blog post on the page unless the user requests.

Could you please provide a simple version of how each of the calls might look like?

Upvotes: 2

Views: 1347

Answers (1)

Jeremy Green
Jeremy Green

Reputation: 8574

1. How to define fixtures? Something else.

The correct form is to embed just the ids as the comments attribute on a post.

App.Post.FIXTURES = [
{
  id:1,
  title:"hello world",
  body:"hey ho",
  comments : [1,2]
},
{
  id:2,
  title:"hello again",
  body:"I'm Bob",
  comments : [3]
}
]

App.Comment.FIXTURES = [
{
  id : 1,
  text: "Very nice"
},
{
  id : 2,
  text: "Very nice indeed"
},
{
  id : 3,
  text: "Pretty cool actually"
}
]

2. Fetching from the server

There are a few ways to go about this.

Use "side loading". You still provide the list of comment ids as the comments attribute, but you also include the list of comments in the JSON response.

{posts:[

    {
      id:1,
      title:"hello world",
      body:"hey ho",
      comments : [1,2]
    },
    {
      id:2,
      title:"hello again",
      body:"I'm Bob",
      comments : [3]
    }
],
comments : [
    {
      id : 1,
      text: "Very nice"
    },
    {
      id : 2,
      text: "Very nice indeed"
    },
    {
      id : 3,
      text: "Pretty cool actually"
    }
]}

Use async on your hasMany to allow Ember to look up the comments after the post has already been loaded.

App.Post = DS.Model.extend({
  comments: DS.hasMany('comment',{async:true})
});

If you have thousands of records the solutions above aren't going to be much good. Instead of loading all of the comments at one time (either with side loading or async) you'll want to use pagination to load only a few comments at a time. In that case your PostRoute and PostController might look something like this.

App.PostController = Ember.ObjetController.extend({
  needs : ['comments']
});

App.PostRoute = Ember.Route.extend({
  setupController : function(controller,model){
    this._super(controller,model);
    comments = this.store.find('comment',{post_id : model.get('id'), page : 1});
    this.controllerFor('comments').set('content',comments);
  }
});

Upvotes: 4

Related Questions