hilem
hilem

Reputation: 23

Infinite Loop in Ember-Data clearRelationships?

Inquiry:
Can anybody tell me why I might be getting an infinite loop when attempting to delete an Ember-Data Model. Stepping through the crash, the issue appears to be in clearRelationships, but no matter how minimal I attempt to make the Model relationships I can't seem to get away from the infinite loop, without avoiding them all together.


Relevant Code:

//// Config
App = Ember.Application.create();
App.Adapter = DS.RESTAdapter.extend();
App.store = DS.Store.create({
  revision: 11,
  adapter: App.Adapter.create()
});
App.Router = Ember.Router.extend({});
App.Router.map(function() {
  this.resource('main', { path: '/' });
});

//// Models
App.Scientist = DS.Model.extend({
  name:     DS.attr('string'),
  tests:    DS.hasMany('App.Tests'),
  criteria: DS.belongsTo('App.Criteria')
});
App.Test = DS.Model.extend({
  name:      DS.attr('string'),
  scientist: DS.belongsTo('App.Scientist'),
  criteria:  DS.belongsTo('App.Criteria')
});
App.Criteria = DS.Model.extend({
  name:      DS.attr('string'),
  scientist: DS.belongsTo('App.Scientist'),
  test:      DS.belongsTo('App.Test'),
  resources: DS.hasMany('App.Resource')
});
App.Resource = DS.Model.extend({
  name:     DS.attr('string'),
  criteria: DS.belongsTo('App.Criteria')
});

//// Pre-Load Models
App.store.loadMany(App.Test,
  [{id:'1', scientist_id:'1', name:'gravity', criteria_id:'2'},
   {id:'2', scientist_id:'1', name:'not gravity', criteria_id:'3'}]);
App.store.load(App.Scientist, 
  {id:'1', name:'Bill', tests:['1', '2'], criteria_id:'1'});
App.store.load(App.Criteria, 
  {id:'1', name:'control', scientist_id:'1', test_id:null, resources:['1']});
App.store.loadMany(App.Criteria,
  [{id:'2', name:'variation1', scientist_id:null, test_id:'1', resources:['2','3']},
   {id:'3', name:'variation2', scientist_id:null, test_id:'2', resources:['4','5']}]);
App.store.loadMany(App.Resource, 
  [{id:'1', name:'resource1', criteria_id:'1'},
   {id:'2', name:'resource2', criteria_id:'2'},
   {id:'3', name:'resource3', criteria_id:'2'},
   {id:'4', name:'resource4', criteria_id:'3'},
   {id:'5', name:'resource5', criteria_id:'3'}]);

var filter = App.Test.filter(
  function(model) { if (model.get('isLoaded') === true) { return model; } }
);

App.MainRoute = Ember.Route.extend({
  setupController: function(controller, model) {
    controller.set('tests', filter);
  }
});

///// Controller
App.MainController = Ember.ArrayController.extend({
  name: 'Main',
  createTest: function() {
    App.Test.createRecord();
    App.store.commit();
  },
  removeTest: function(test) {
    test.deleteRecord();
    App.store.commit();
  }
});

Steps to Reproduce:
http://jsfiddle.net/hilem/GMt7H/

1) Open Browser Console.
2) Run the fiddle.
3) Watch console as you hit remove on one of the list items.


Update 1 (8:44PM 1/27/2013)
Additional Context: This is using ember-1.0.0-pre.4.js && the latest commit of ember-data on master as of 1/27/2013. I also added a bit more to the example code above.


Update 2 (5:25PM 2/1/2013)
Bump! Issue still exists, there seems to be quite a few issues involving deleteRecord lately on github issue tracker that sound similar to my issue. Here's a link to my specific issue on the tracker:
https://github.com/emberjs/data/issues/671

Upvotes: 1

Views: 523

Answers (2)

Devin Crossman
Devin Crossman

Reputation: 7592

It's a bug. This pull request on Github fixed it for me. https://github.com/emberjs/data/pull/715

Upvotes: 1

Devin Crossman
Devin Crossman

Reputation: 7592

I was having a similar issue. I had models like these

App.User = DS.Model.extend({
  account: DS.belongsTo('App.Account'),
  name: DS.attr('string')

});

App.Account = DS.Model.extend({
  user: DS.belongsTo('App.User'),
  type: DS.attr('string')
});

The recursion isn't actually happening in clearRelationships but in this section of the ember.js set method

var meta = obj[META_KEY], desc = meta && meta.descs[keyName],
      isUnknown, currentValue;
  if (desc) {
    desc.set(obj, keyName, value);
  } else {
   ....
  }

when I deleted the User it tried to clearRelationships which calls set(this, "account", null) which eventually gets to the section above which calls set again and again and again.

I'm not sure the right way to fix this but I got it to work in my situation by removing the user belongsTo relationship on the account. so my new models look like this

App.User = DS.Model.extend({
  account: DS.belongsTo('App.Account'),
  name: DS.attr('string')

});

App.Account = DS.Model.extend({
  // user: DS.belongsTo('App.User'),
  type: DS.attr('string')
});

Upvotes: 0

Related Questions