lundi 27 février 2017

How to generate a child model dependant on data from it's parent with ember-factory-guy?

What's the best way to have the data generated in a child model be dependant on data from the parent?

Two particular examples of what I'm trying to accomplish:

  1. I have two types of (one-to-one) linked models that, if linked, will be returned from the API with the same name. So if I create a parent object with a given name, i'd like the child to inherit the same name

  2. the models also have creation timestamps. The childrens' timestamps should be the parent's plus some delta, and the grandchildrens' should be their parent's (the "child" model) plus some additional delta

So, given these models:

Parent = DS.Model.extend({
  name: DS.attr('string'),
  child: DS.belongsTo('child'),
  createdAt: DS.attr('date')
})

Child = DS.Model.extend({
  name: DS.attr('string'),
  parent: DS.belongsTo('parent'),
  children: DS.hasMany('grandchild'),
  createdAt: DS.attr('date')
})

Grandchild = DS.Model.extend({
  parent: DS.belongsTo('child'),
  createdAt: DS.attr('date')
})

Two things I tried:

Approach #1: Using an inline function on the child properties hash that I'm embedding in the parent factory definition

// tests/factories/parent.js

FactoryGuy.define('parent', {
  default: {
    child: FactoryGuy.belongsTo('child', {
      name: (parent) => parent.name,
      createdAt: (parent) => new Date(parent.createdAt.getTime() + OFFSET),
      grandchildren: FactoryGuy.hasMany('grandchild', {
        createdAt: (child) => new Date(parent.createdAt.getTime() + OFFSET)
      });
    })
  }
});


// tests/factories/child.js

FactoryGuy.define('child', {
  default: {
    grandchildren: FactoryGuy.hasMany('grandchild', {
      createdAt: (child) => new Date(child.createdAt.getTime() + OFFSET)
    });
  }
});

I was hoping these functions would recieve the parent object, but instead this seems to just directly assign the function as the value of the field on the child object.

Approach #2: Accessing related objects from inline functions

// tests/factories/child.js

FactoryGuy.define('child', {
  default: {
    name: (child) => child.parent.name,
    createdAt: (child) => new Date(child.parent.createdAt.getTime() + OFFSET),
    grandchildren: FactoryGuy.hasMany('grandchild')
  }
});


// tests/factories/grandchild.js

FactoryGuy.define('grandchild', {
  default: {
    createdAt: (grandchild) => new Date(grandchild.parent.createdAt.getTime() + OFFSET)
  }
});

This just blows up with TypeError: Cannot read property 'createdAt' of undefined (ie the related model isn't available yet)

So, how should this be done?




Aucun commentaire:

Enregistrer un commentaire