Model "is a" Relationship


#1

Hi, I am very new to Ember.

I have an “associate” model and a “collector” model, which extends associate. Collector is also a subset of associate and no associate can be duplicated in collector.

//associate model import DS from ‘ember-data’;

export default DS.Model.extend({
   associateId: DS.attr('number')
  ,lastName: DS.attr('string')
  ,firstName: DS.attr('string')
  ,nickname: DS.attr('string')
  ,phoneExtension: DS.attr('string')
});

//collector model import DS from ‘ember-data’; import associate from ‘./associate’;

export default associate.extend({
   isSpanishSpeaker: DS.attr('number')
  ,isConciergeEligible: DS.attr('number')
  ,shiftName: DS.attr('string')
  ,isActive: DS.attr('number')
  ,subscriptions: DS.hasMany('call-queue')
});

I’m having trouble finding the correct “Ember way” to model this relationship.

  1. I want to be able to pick members from associate and add them to collector
  2. I want to create a pick list of associates that are not collectors
  3. When I add an associate to the collector set, I want the pick list in #2 to remove that associate from its list.

Finally, the action below, “addAssociateToCollectors()”, is giving me the following error: “Assertion Failed: Ember.Object.create no longer supports defining computed properties. Define computed properties using extend() or reopen() before calling create().”.

The setDiff is also not working.

//controller for my ‘add’ template for collector

export default Controller.extend({
	 associateToAdd: null
	,availableAssociates: setDiff('model.associates', 'model.collectors') //this does not work

	,actions: {
		setAssociateToAdd(value) {
		   this.set('associateToAdd', value); //set by picklist in template
		}
		,addAssociateToCollectors() {
		   this.store.createRecord('collector', {
			  associateId: this.associateToAdd.id
			 ,firstName: this.associateToAdd.firstName
			 ,lastName: this.associateToAdd.lastName
			 ,nickname: this.associateToAdd.nickname
			 ,phoneExtension: this.associateToAdd.phoneExtension
			 ,isSpanishSpeaker: 0
			 ,isConciergeEligible: 0
			 ,shiftName: 'Variable'
			 ,isActive: 1
			 ,subscriptions: null
		   });
		}
	}
});

I’d appreciate any help anyone can offer. Or, if there are docs that address this that I’m missing, please point me in the right direction.

Thank you.


#2

First off, I think your assertion is happening because you are trying to add the raw attribute definition to your new model: “this.associateToAdd.id” is a DS.attr() , you want the property’s value: “this.associateToAdd.get(‘id’)”

Try replacing all of the ‘this.associate.x’ properties in your createRecord with constant strings and numbers briefly to see if that removes the assertion - if so, then that is the problem.

In terms of your primary question, I think in Ember you would need to do the ‘createRecord’ of collector like you are doing and then do a destroyRecord of the old associate.

Something to consider - what if you made the collector a ‘role’ of an associate, and then made your ‘role’ class polymorphic? Then you could just createRecord a role and add it to the existing associate. The picklist would filter on role !== collector and the collectors would be role === collectors

Then you never have to destroy an associate just because you’ve ‘promoted’ it to collector.

Edit: Also, the setDiff is not going to recognize a particular associate record as matching a particular collector record, since they are completely different records and Ember doesn’t have any way of knowing that you consider them to be the same one.


#3

Thank you! I’ll pursue these ideas and check back in here later today.


#4

You were right about the createRecord error.

Your suggestion about the ‘role’ attribute helped me rethink the relationship. I’m now loading all associates and just filtering between collectors and non-collectors. That eliminated all of the semantic problems and greatly reduced the amount of code.

Thanks, again.