Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

performing rollback on model with hasMany relation

I have models defined as :

App.Answer = DS.Model.extend({
    name: DS.attr('string'),
    layoutName: DS.attr('string')
});

App.Question = DS.Model.extend({
    name: DS.attr('string'),
    answers: DS.hasMany('answer', {async: true})
});

I have a component that allows for deleting and adding answers to question model. The component comes with apply and cancel button and when the user clicks on cancel, I wanted all the changes(adds/deletes of answers) to be reverted. Currently rollback doesn't do the trick, I event tried model.reload() when using rest adapter and that didn't work for me either. Any idea how I can go about doing a rollback in this situation?

When using the rest adapter, I pretty much fall to the issue pointed here : EmberJS cancel (rollback) object with HasMany

Thanks, Dee

UPDATE :

Since I couldn't perform rollback the intended way, I performed these steps:

1) get all the answers back from the server
2) remove answer association from the question
3) manually add answer association to the question model from data received from server

This seems to be working well BUT sadly I am getting this one error that I cannot shake off.

Here is a jsbin of updated progress: http://jsbin.com/uWUmUgE/2/

Here you can create new answer and then append it to question and do rollback too. BUT, if you follow these steps, you will see the issue I am facing:

1) delete an answer
2) add an answer
3) perform rollback
4) add an answer

It throws this error: Error: Attempted to handle event didSetProperty on while in state root.deleted.uncommitted. Called with {name: position, oldValue: 1, originalValue: 1, value: 2}.

I will super appreciate any help you can provide.

WORK-AROUND:

One simple workaround was to just hide the answers on delete. I modified the model a bit like:

App.Answer = DS.Model.extend({
    name: DS.attr('string'),
    layoutName: DS.attr('string'),
    markToDelete: DS.attr('boolean', {default: false})
});

And my rollback function had this logic:

answers.forEach(function (answer) {
    if(!answer.get('id')){
        //newly created answer models that has not persisted in DB
        question.get('answers').removeObject(answer);
        answer.deleteRecord();
    } else {
        answer.rollback();
    }
});
like image 377
Deewendra Shrestha Avatar asked Jan 10 '14 20:01

Deewendra Shrestha


1 Answers

I'm not sure of your scope but for this relationship (I'm actually rolling back the belongsTo here but I'm curious if this helps in any way)

   App.Appointment = DS.Model.extend({
        name: DS.attr('string'),
        customer: DS.belongsTo('customer', {async: true})
    });

    App.Customer = DS.Model.extend({
        name: DS.attr('string'),
        appointments: DS.hasMany('appointment', {async: true})
    });

I'm able to rollback both the appointment and it's hasMany customer model like so (from within my route)

App.AppointmentRoute = Ember.Route.extend({
actions: {
  willTransition: function(transition) {
    var context = this.get('context');
    var dirty =context.get('isDirty');
    var dirtyCustomer=context.get('customer.isDirty');  
    var message = "foo";
    if ((dirty || dirtyCustomer) && confirm(message)) {
        transition.abort();
    }else{
        context.get('customer').get('content').rollback();
        context.rollback();return true;
    }
}
});
like image 151
Toran Billups Avatar answered Nov 02 '22 21:11

Toran Billups