How can you have one model with multiple polymorphic associations?


#1

I’m getting an assertion error about adding records of polymorphic type that don’t inherit from the defined type:

Uncaught Error: Assertion Failed: You cannot add a record of type 'recipe' to the 'build-item.item' relationship (only 'item' allowed)

Using 2.3.0, it’s coming from here. I’m not really sure why ED cares about this at all (especially with JSONApiAdapter) but okay I get it I need to change something.

The problem is I have one model that must be able to be polymorphic for two different models. Take the following:

Build = DS.Model.extend({
   builder: belongsTo('builder')
});

BuildItem = DS.Model.extend({
  build: DS.belongsTo('build'),
  item: DS.belongsTo('item')
});

Builder = DS.Model.extend({});
Item = DS.Model.extend();

// Ingredient is only an Item... so this works fine
Ingredient = Item.extend();

// Product is only a Builder... so this works fine
Product = Builder.extend();

// Recipe is both a Builder and an Item...
Recipe = Builder.extend();

How can I define Recipe as both an Item and a Builder so that ED doesn’t stop in it’s tracks for some reason?

Also, it doesn’t make sense that ember data would hard code privately the check without bringing this up to the model level.

Side Note: Ember data has a tagged release version 2.3.3 which has removed this check from the production build but installing via ember install ember-data@2.3.3 still includes a build a where the assertion error is still there and raising… not sure what is going on there.


#2

I know this is dated, but recently (Ember 2.7) I was able to get around this by have a hierarchy of inheritance. It’s kind of ugly, I think, but essentially it worked like this:

// bookmarkable.js
public DS.Model.extend({
  bookmarks: DS.hasMany('bookmark')
});

// taggable.js
import Bookmarkable from 'my-app/models/bookmarkable';
public Bookmarkable.extend({
  tags: DS.hasMany('tag')
});


// app/models/my-item.js
import Taggable from 'my-app/models/taggable';
public Taggable.extend({ });`

// app/models/tag.js
public DS.Model.extend({
  taggable: DS.belongsTo('taggable', { polymorphic: true })
});

// app/models/bookmark.js
public DS.Model.extend({
  bookmarkable: DS.belongsTo('bookmarkable', { polymorphic: true })
});

It only seems to work because all my Bookmarkable things also happen to be Taggable. I’m not sure what I would do if they were disjoint sets.

P.S. It seems like I was forced to set: Ember.MODEL_FACTORY_INJECTIONS = false; for this to work, but I can’t be sure I didn’t have some other error.