New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allows parent classes to resolve subclasses when loading data. #24

Merged
merged 3 commits into from Mar 16, 2016

Conversation

Projects
None yet
2 participants
@alexraginskiy
Copy link
Contributor

alexraginskiy commented Mar 16, 2016

This stores subclasses when a model is extended.

Providing a getSubclass function on the class allows the parent class to resolve a subclass to instantiate when loading.

var Parent = Model.extend('Parent', function() {
  this.prototype.init = ()=> {};

  this.getSubclass = function(attrs) {
    return attrs.type;
  };
});

var Child = Parent.extend('Child', function() {
  this.prototype.init = ()=> {};
});

var AnotherChild = Parent.extend('AnotherChild', function() {
  this.prototype.init = ()=> {};
});

var Composition = Model.extend('Composition', function() {
  this.hasMany('things', 'Parent');
});

var compostion = Composition.load({
  id: 1,
  things: [
    {
      id: 'thing1',
      type: 'Child'
    },
    {
      id: 'thing2',
      type: 'AnotherChild'
    }
  ]
});

composition.things[0] instanceof Child;
// true

composition.things[1] instanceof AnotherChild;
// true
@@ -175,9 +175,21 @@ var Model = TransisObject.extend(function() {

if (typeof f === 'function') { f.call(subclass); }

if(this.displayName !== 'Transis.Model') {
this.subclasses = this.subclasses || [];
this.subclasses.push(name);

This comment has been minimized.

@burrows

burrows Mar 16, 2016

Member

Can't you use the private subclasses object instead?

This comment has been minimized.

@burrows

burrows Mar 16, 2016

Member

Actually, this would be necessary in order to ensure that you are getting an actual subclass of the receiver.

return subclass;
};

this.resolveSubclass = function(name) {
if(!this.subclasses) { throw new Error(`${this}.resolveSubclass: ${this} does not have subclasses`); }
if(this.subclasses.indexOf(name) < 0) { throw new Error(`${this}.resolveSubclass: could not find subclass ${name}`); }

This comment has been minimized.

@burrows

burrows Mar 16, 2016

Member

I think only one error message is necessary there:

if (!this.subclasses || this.subclasses.indexOf(name) < 0) {
  throw new Error(`${this}.resolveSubclass: could not find subclass ${name}`);
}
@@ -394,7 +406,15 @@ var Model = TransisObject.extend(function() {
loads.push(true);

attrs = Object.assign({}, attrs);
model = IdMap.get(this, id) || new this;
if(typeof this.getSubclass === 'function') {

This comment has been minimized.

@burrows

burrows Mar 16, 2016

Member

You could provide a default implementation of getSubclass that returns this.displayName. Then you wouldn't need the typeof check.

This comment has been minimized.

@alexraginskiy

alexraginskiy Mar 16, 2016

Contributor

but this.displayName would not be found by this.resolveSubclass

burrows added a commit that referenced this pull request Mar 16, 2016

Merge pull request #24 from centro/subclass-associations
Allows parent classes to resolve subclasses when loading data.

@burrows burrows merged commit fc662cb into master Mar 16, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment