Polymorphic relations are currently the pain point for me (I hope for other people as well) in complex scenarios. Here is how we create complex polymorphic model relations right now:
Child models:
App.Foo = DS.Model.extend({
fooBarable: DS.belongsTo('foo-bar', { polymorphic: true })
});
App.Bar = DS.Model.extend({
fooBarable: DS.belongsTo('foo-bar', { polymorphic: true })
bazBarable: DS.belongsTo('bar-baz', { polymorphic: true })
});
App.Baz = DS.Model.extend({
bazable: DS.belongsTo('bar-baz', { polymorphic: true })
});
Mixins that will make multiple associations possible:
App.Fooable = Ember.Mixin.create({
foos: DS.hasMany('foo')
});
App.Barable = Ember.Mixin.create({
bars: DS.hasMany('bar')
});
App.Bazable = Ember.Mixin.create({
bazs: DS.hasMany('baz')
});
Objects which we will extend to create parent objects (and which contain different combinations of child objects):
App.FooBar = DS.Model.extend(
Fooable, Barable, {});
App.BarBaz = DS.Model.extend(
Barable, Bazable, {});
Parent objects
App.Father = FooBar.extend({
});
App.Mother = BarBaz.extend({
});
With 3 child objects and 2 parent objects we needed to create 3 mixins and 2 objects (additional 5 objects) from which parent objects will inherit. And this is a fairly simple scenario; once things get more complex (and they always do in larger projects) this will be a nightmare to maintain.
I want to propose a change into the public API which will help developers to define polymorphic models in a cleaner way (Ruby on Rails is a huge inspiration here — Active Record Associations — Ruby on Rails Guides):
Child objects:
App.Foo = DS.Model.extend({
fooable: DS.belongsTo('fooable', { polymorphic: true })
});
App.Bar = DS.Model.extend({
barable: DS.belongsTo('barable', { polymorphic: true })
});
App.Baz = DS.Model.extend({
bazable: DS.belongsTo('bazable', { polymorphic: true })
});
Parent objects
App.Father = DS.Model.extend({
foos: DS.hasMany('foo', { as: 'fooable' }),
bars: DS.hasMany('bar', { as: 'barable' })
});
App.Mother = DS.Model.extend({
bars: DS.hasMany('bar', { as: 'barable' }),
bazs: DS.hasMany('baz', { as: 'bazable' })
});
So instead of creating 5 more additional objects and writing code that is hardly readable and a nightmare to maintain we could have relations defined on the models in a cleaner way.
Unfortunately I am not familiar with Ember-data internals and I am not sure about feasibility of this proposal. I will start digging into Ember-data slowly in attempt to learn more and to craft pull request one day. Meanwhile feedback (and help) is welcomed!