0

I have two properties in my user model school_id and school_name because I allow users to specify their own school if the list I provide is not enough. This should be universal to a User. The Ember documention seemingly suggests bindings but only provides aliased values or ones that need to be the same value. Observables seem appropriate, but what is best and how? Ideally, I'd like to specify this at the model level.

Models.User = DS.Model.extend({
  schoolName: DS.attr("string"),
  school: DS.belongsTo("school", {async: true })
});

What I want is that when I set schoolName, school is set to null, and when school is set, schoolName is set to null.

The Rails model equivalent of what I'm after:

class User < ActiveRecord::Base      
  def nces_high_school_id=(value)
    write_attribute(:school_name, nil)
    write_attribute(:school_id, value)
  end
  def school_name=(value)
    write_attribute(:school_id, nil)
    write_attribute(:school_name, value)
  end
end
Michael
  • 1,786
  • 5
  • 23
  • 42

1 Answers1

1

You can add observers to your properties, and react to changes (http://emberjs.com/api/classes/Ember.Observable.html#toc_observing-property-changes).

You need something like this, to accomplish what you want:

App.User = DS.Model.extend({
    schoolName: DS.attr("string"),
    school: DS.belongsTo("school", {async: true }),

    _suspendValueChange: false,

    schoolUpdateObserver: function() {
        if (this.get('school') && this.get('_suspendValueChange') == false)  {
            this.set('_suspendValueChange', true);
            this.set('schoolName', undefined);
            this.set('_suspendValueChange', false);
        }
    }.observes('school'),

    schoolNameUpdateObserver: function() {
        if (this.get('schoolName') && this.get('_suspendValueChange') == false)  {
            this.set('_suspendValueChange', true);
            this.set('school', undefined);
            this.set('_suspendValueChange', false);
        }
    }.observes('schoolName')
});

I havent tested all senarios, but this works as expected:

_this = this;
this.store.find('school', 1).then(function(school) {
    var user = _this.store.createRecord('user');
    user.set('school', school); // => schoolName is set to undefined, and school is set to the school record.
    user.set('schoolName', 'test'); // => school is set to undefined, and schoolName is set to 'test'.
    user.set('school', school); // => schoolName is set to undefined, and school is set to the school record.
});
Martin
  • 2,302
  • 2
  • 30
  • 42