Model belongs to more than one other models


#1

I consumer an API that re-uses some models. What I want to do is re-use my ember model in several others using the hasMany and belongsTo.

Example code:

// Furniture model
export default DS.Model.extend({
  parent: DS.belongsTo('what goes here??'),
  color: DS.attr(),
  type: DS.attr()
});

// House model
export default DS.Model.extend({
  name: DS.attr(),
  furnitures: DS.hasMany('furniture')
});

// School model
export default DS.Model.extend({
  name: DS.attr(),
  furnitures: DS.hasMany('furniture')
});

Could someone please explain to me whether this is possible and how it is achieved?


#2

You only need need to declare the relationship on both sides if you’ll need to be able to lookup records in both directions (eg. “Get the House record that this Furniture is a part of”). In your case, you probably just need the hasMany, since your House or School model will probably always be loaded before.

That said, if you DID want to it, it would look like this:

// Furniture model
export default DS.Model.extend({
  house: DS.belongsTo('house'),
  school: DS.belongsTo('school'),
  color: DS.attr(),
  type: DS.attr()
});

#3

There’s actually a second option here with polymorphic relationships.

Here’s a good presentation on it: http://lukegalea.github.io/ember_data_polymorphic_presentation/ (Haven’t vetted how up-to-date it is).

In your case, your models would look like:

// Furniture model
export default DS.Model.extend({
  parent: DS.belongsTo('house', {polymorphic: true}),
  color: DS.attr(),
  type: DS.attr()
});

// House Model
export default DS.Model.extend({
  name: DS.attr(),
  furnitures: DS.hasMany('furniture')
});

// School Model
import house from './house/model';
export default house.extend({
  // Any school specific model stuff here.
});

#4

Nice call out on polymorphic relationships! I don’t think I’ve ever used a polymorphic belongsTo before. In this case, however, is School a type of House? It seems more likely that they would both be a type of Buidling. Eg:

// Furniture model
export default DS.Model.extend({
  furniture: DS.belongsTo('building', {polymorphic: true}),
  color: DS.attr(),
  type: DS.attr()
});

// Building Model
export default DS.Model.extend({
  name: DS.attr(),
  furnitures: DS.hasMany('furniture')
});

// House Model
import House from './buiding/model';
export default Building.extend({
  // Any house specific model stuff here.
});

// School Model
import House from './building/model';
export default Building.extend({
  // Any school specific model stuff here.
});

#5

Thank you both for your responses. My models are not the same (school and house here are just a simplified example).

Althouth I guess having a common model which others extend can work fine. I will try this out as soon as I get to the office and let you know how it went.


#6

Yes, that’s probably how it should be done. :slight_smile:


#7

The example from @kylecoberly works great. The only change is that there is no need to add polymorphic: true. Thank you guys again.


#8

Hey folks,

I’m curious how you get this to work from both sides? I can’t seem to get the model reference to exist for both sides (only one).