1
votes

I have following models:

App.Parent = DS.Model.extend({
  foo: DS.attr('string'),
  children: DS.hasMany('child', {async: true})
});

App.Child = DS.Model.extend({
  bar: DS.attr('string')
});

I filled them with some fixture data:

App.ApplicationAdapter = DS.FixtureAdapter.extend();

App.Parent.FIXTURES = [
  {
    id:0,
    foo: 'parent',
    children: [0,1]
  }
];

App.Child.FIXTURES = [
  {
    id: 0,
    bar: 'child 0'
  },
  {
    id: 1,
    bar: 'child 1'
  },
  {
    id: 2,
    bar: 'child 2'
  }
];

After I do some changes to the children relation, how can I rollback children relation to its latest saved state?

I push new child to manyArray in the following way:

this.store.find('child', 2).then(function(child){
  model.get('children').pushObject(child);
})

This does change the relation (I see new child in my view), but parent record does not become dirty. Thus, when I try model.rollback() it does nothing. I also tried solution I found here How to rollback relationship changes in EmberData which is adding model.send('becomeDirty') before rollback, but it does not help.

Maybe I am adding children to my relation in a wrong way?

Thanks!

4

4 Answers

2
votes

I used this to rollback related records that are dirty.

App.ParentRoute = Ember.Route.extend 
  model: ->
    @get('store').createRecord('parent', child: @get('store').createRecord('child'))
  actions:
      willTransition: (transition) ->
        rollbackRecords(@)

rollbackRecords = (context) ->
  if context.get("controller.content.isDirty")
    relationships = Ember.get(App[context.get('controller').resourceName], "relationshipsByName")
    content = context.get('controller.content')
    relationships.forEach (name, relationship) ->
      relatedModel = content.get(name)
      relatedModel.rollback() if relatedModel? and relatedModel.get('isDirty')
    content.rollback()
  true
2
votes

Here is some code that will rollback a model, as well as it's relationships that I use:

    var model = this.get('model');
    var relatedModel, relatedModels;
    model.constructor.eachRelationship(function (key, relationship) {
        if (relationship.kind === 'hasMany') {
            relatedModels = model.get(key);
            if (relatedModels) {
                relatedModels.invoke('rollback'); //since this is an array, need to call the rollback function differently
            }
        }
        else {
            relatedModel = model.get(key);
            if (relatedModel) {
                relatedModel.rollback();
            }
        }
    });
    model.rollback();

Hope this helps

2
votes

I believe the other answers listed here only partially solve this problem. If you add a new related model or remove an existing one, rollback should reverse those as well and I believe the other answers don't address this. Here is a complete solution that provides proper dirty checking and a complete rollback for hasMany and belongsTo relationships:

https://stackoverflow.com/a/27184207/188740

0
votes

I like to do the good ol' model.reload() - it'll blow away all changes you haven't synced with your server though.