mercredi 24 juin 2015

understand ember preloding/sideloading associated records

While experimenting with ember and ember-localforage-adapter I need to better understand when sideloading or kind of is necessary.

ember.debug.js:4888DEBUG: Ember      : 1.12.0
ember.debug.js:4888DEBUG: Ember Data : 1.0.0-beta.19
ember.debug.js:4888DEBUG: jQuery     : 1.11.3

I have three models:

/app/models/ledger.js

import DS from 'ember-data';

export default DS.Model.extend({
  title: DS.attr('string'),

  purchases: DS.hasMany('purchase', {async: true}),
  players: DS.hasMany('player', {async: true}),
});

/app/models/purchase.js

import DS from 'ember-data';

export default DS.Model.extend({
  name: DS.attr('string'),
  amount: DS.attr('number'),

  ledger: DS.belongsTo('ledger', {async: true}),
  player: DS.belongsTo('player', {async: true})
});

/app/models/player.js

import DS from 'ember-data';

export default DS.Model.extend({
  name: DS.attr('string'),
  balance: DS.attr('number'),

  ledger: DS.belongsTo('ledger',{ async: true }),
  purchases: DS.hasMany('purchase', {async: true}),
});

and this route:

/app/routes/ledger/purchases.js

import Ember from 'ember';

export default Ember.Route.extend({
  model: function(params) {
    var store = this.get("store");
    var ledger = this.modelFor('ledger');


    store.find('purchase');                        // <--- I need this!
    store.find('purchase', {ledger: ledger.id});   // <--- or this!

    return this.modelFor('ledger').get('purchases');
  }
});

In order to use {{model.player.name}}in the following I need the above highlighted calls otherwise I got it as undefined

/app/templates/ledger/purchases/index.hbs

....
{{#each model itemController='ledger.purchases.item' }}
  <li class="list-group-item">
    {{model.name}}
    {{model.ledger.title}} // <--- this is OK
    {{model.player.name}}  // <--- this needs preloading
  </li>
{{/each}}
....

As I found this workaround nearly by chance I wonder whether this the right way to have it done. It seems that to access associated records they need to be (pre)loaded in the store someway. Anyway it doesn't seem so DRY so I think that something is wrong.

note

It works also with only return store.find('purchase', {ledger: ledger.id}); but then my actions in controllers get more complicated. Is this the way to go and my actions crappy?




Aucun commentaire:

Enregistrer un commentaire