ember-data-model-fragments icon indicating copy to clipboard operation
ember-data-model-fragments copied to clipboard

FragmentArray.createFragment should respect `type` in polymorphic arrays

Open DocX opened this issue 5 years ago • 3 comments

If I have polymorphic fragment array:

export MyModel = DS.Model.extend({
  parts: MF.fragmentArray('part', { polymorphic: true }),
});

with hierarchic fragment models:

export Part = MF.Fragment.extend({
  // ...
}

export PartOne = Part.extend({
  // ...
}

And then I want to create fragment directly on the array, with given type:

myModel.get('parts').createFragment({
  type: 'part-one',
  fields: ...
});

It does not respect the type passed. Rather it always creates the fragment with the type declared in the definition of the fragmentArray. As it can be seen in the code here:

https://github.com/lytics/ember-data-model-fragments/blob/master/addon/array/fragment.js#L244

Is there reason for this? Would it make sense to look for the typeKey in the given object to createFragment and use that if the array definition is polymorphic?

DocX avatar Oct 15 '18 16:10 DocX

Here's a workaround,

import FragmentArray from 'ember-data-model-fragments/array/fragment';

FragmentArray.reopen({
  createFragment(props) {
    const type = props?.type || this.type;
    const fragment = this.owner.store.createFragment(type, props);
    return this.pushObject(fragment);
  },
});

dwickern avatar Oct 29 '21 21:10 dwickern

@dwickern I tried to adjust the code to work in apps with both monomorphic and polymorphic fragment arrays, which now seems to work ok for my usecases:

FragmentArray.reopen({
  createFragment(props) {
    const record = this.owner;
    let modelName = this.type;

    // Determine modelName for polymorphic relationships
    if (this.options.polymorphic) {
      const typeKey = this.options.typeKey || 'type';
      if (typeof typeKey === 'function') {
        modelName = typeKey(props, record);
      } else {
        modelName = props[typeKey];
      }
    }

    const fragment = record.store.createFragment(modelName, props);
    return this.pushObject(fragment);
  },
});

iStefo avatar Apr 10 '22 18:04 iStefo

@iStefo could you PR this?

knownasilya avatar Apr 11 '22 16:04 knownasilya