-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Rollback Relationships #2881
Rollback Relationships #2881
Conversation
dfc9f03
to
6a095f8
Compare
6a095f8
to
2eacc52
Compare
2eacc52
to
b83c4c4
Compare
Thanks! I will bring this up at friday's meeting. |
Thanks @mmpestorich! This solves a very painful point of ember data. Are there any news on having this merged? |
What is the state on this? We're currently managing our relation rollback by hand and it gets very confusing sometimes. |
+1 |
I'm going to close this pr. @igorT is working on an RFC to describe what needs to happen to for Ember Data to support relationship rollback. |
@bmac This pull request implements rollback for both belongsTo and hasMany relationships. @igorT work in #3698 only addresses belongsTo relationships. If it's a matter of more discussion, conforming to an RFC, cleaning up the code, etc... please point me in the right direction. I'll gladly help in anyway that I can. This PR has been sitting out here for over a year now with no feedback from the ember-data team... slightly frustrating. Prior to this, I had pushed up #1631 - which I closed after being told that rolling back relationships would be addressed by the single-source-of-truth branch - ulitmately it wasn't. The bottom line is that this PR works and has a handful of passing tests and it's been over 2 years since ember-data was able to rollback relationships (when this behavoir was removed from ember-data, it was sold as a temporary thing). I'd gladly contribute more time and energy to this in order to put something together that you all would feel comfortable accepting... anything I can do please let me know. There's up to date version of this commit here |
@mmpestorich It looks really nice, but I am wondering if it is also working correctly after you've saved a record. I've also implemented something like this myself, but |
@steffenbrem Hm... our UI doesn't allow a rollback after a record has been saved so I don't think I've ever encountered that. I'll create a test and look into what it would take to handle that properly. |
@mmpestorich I think it is a common scenario, lets say you have a A code example to illustratie this use-case: parent.get(‘children’); // []
// we add our first child
parent.get(‘children’).pushObject(child1);
// we save parent and it's linked child record
parent.save().then(() => {
// add another child
parent.get(‘children’).pushObject(child2);
parent.rollback();
// this will be empty, but you would expect it to contain `child1`
parent.get(‘children’); // []
}); |
A way to solve it is to let the API return the ids of the |
@steffenbrem Ok, couple things.... I added a test that passes the parent-child scenario you outlined above. Both The dirtyRecordFor hooks that I added back to With that said, I realize that there are a lot of people using some form or fashion of a NoSQL database in which it might make more sense to simply |
@mmpestorich Thanks for taking time to look into this 😃! You are indeed right that people manage their relationships differently in Ember Data, but I think there should be a mechanism build in to update the canonicalState of relationships when the parent is saved. I am using a RDMS btw (not that important), and do persist relationship changes through the parent, simply because it requires much less requests. I don't think saving every relationship independently of the parent is a good solution (at least not in my apps). Right now I use the Do you have an idea on how you can update the canonicalState of all relationships of a parent record that has been saved (without including every relationship in the response)? I have tried to fix this, but I lack the knowledge for it. |
@steffenbrem
😜 Well it just wouldn't be fun if everyone did everything the same way!
I actually agree. On our end we added a To handle commits and rollbacks for multiple records, we rolled our own Basically, we extend var TransactionEnabledModel = DS.Model.extend({
_isDirtyDidChange: function () {
var router = Ember.getOwner(this).lookup('router:main');
var activeTransition = router.get('router.activeTransition');
var record = this;
if (!router.router.currentHandlerInfos) { return; }
handleDirtyChange(activeTransition || router);
function handleDirtyChange(handler) {
if (record.get('isDirty')) {
handler.send('modelBecameDirty', record);
} else {
handler.send('modelBecameClean', record);
}
}
}.observes('currentState.isDirty'),
}); Then we add our var TransactionMixin = Ember.Mixin.create({
transaction: Transaction.create(),
commitPromise: null,
commitTransaction: function () {
var self = this;
this.get('commitPromise', this.get('transaction').commit(this.store))
.then(saveSuccess)
.catch(saveFail)
.finally(clearPromise);
function clearPromise() {
self.set('commitPromise', null);
}
},
actions: {
modelBecameDirty: function (model) {
this.get('transaction').addDirty(model);
},
modelBecameClean: function (model) {
this.get('transaction').removeClean(model);
},
rollback: function () {
this.get('transaction').rollback();
},
commit: function () {
this.commitTransaction();
},
willTransition: function (transition) {
if (this.get('transaction.dirty').length) {
transition.abort();
return false;
}
return true;
}
}
});
var TransactionAwareRoute = Ember.Route.extend(TransactionMixin, { ... }); And of course the actual var Transaction = Ember.Object.extend({
deleted: [],
created: [],
updated: [],
dirty: Ember.computed.union('deleted', 'created', 'updated'),
isDirty: Ember.computed.notEmpty('dirty.[]'),
addDirty: function (model) {
var type = model.get('isNew') ? 'created' : model.get('isDeleted') ? 'deleted' : 'updated';
if (type === 'deleted') {
this.get('updated').removeObject(model);
}
this.get(type).addObject(model);
},
removeClean: function (model) {
this.get('deleted').removeObject(model);
this.get('created').removeObject(model);
this.get('updated').removeObject(model);
},
commit: function (store) {
return store.commitRecords(this.get('dirty'));
},
rollback: function () {
return this.get('dirty').slice().reverse().invoke('rollback');
}
}); Ember Data used to have a transaction api and IMHO it worked pretty well. I was disappointed when it was removed. I don't know if any of this helps, but along with the code in this PR it made working with Ember Data a lot more productive. Without it, I don't think that we could have continued using Ember Data in its current state. There's just too much overhead in manually managing dirty objects on data-heavy pages (again IMHO). |
@steffenbrem
I am currently looking into this and have written a few tests for it, but haven't come up with a good solution yet. If I figure something out, i'll put it up here. |
Thanks for your comments @mmpestorich. I understand the frustration. I think I may have been wrong to close this pull request. Unfortunately, github wont let me reopen this pr. Do you mind submitting a new one and I will get it on the agenda for the next meeting? |
@bmac Sorry for the late response, I've been on vacation these past couple weeks. I'd be more than happy to submit this as a new pull request in order to gather more input from the community and your team. I should be able to get something up by tomorrow. |
This commit: 1. Allows one to rollback belongsTo and hasMany relationships. 2. Reintroduces dirtyRecordFor*Change hooks on the adapter that allow one to customize when a record becomes dirty. 3. Added 'removeDeletedFromRelationshipsPriorToSave' flag to Adapter that allows one to opt back into the old deleted record from many array behavior (pre emberjs#3539). Known issues: 1. Rolling back a hasMany relationship from the parent side of the relationship does not work (doing the same from the child side works fine). See test that is commented out below as well as the discussion at the end of emberjs#2881#issuecomment-204634262 This was previously emberjs#2881 and is related to emberjs#3698
This commit: 1. Allows one to rollback belongsTo and hasMany relationships. 2. Reintroduces dirtyRecordFor*Change hooks on the adapter that allow one to customize when a record becomes dirty. 3. Added 'removeDeletedFromRelationshipsPriorToSave' flag to Adapter that allows one to opt back into the old deleted record from many array behavior (pre emberjs#3539). Known issues: 1. Rolling back a hasMany relationship from the parent side of the relationship does not work (doing the same from the child side works fine). See test that is commented out below as well as the discussion at the end of emberjs#2881#issuecomment-204634262 This was previously emberjs#2881 and is related to emberjs#3698
This commit: 1. Allows one to rollback belongsTo and hasMany relationships. 2. Reintroduces dirtyRecordFor*Change hooks on the adapter that allow one to customize when a record becomes dirty. 3. Added 'removeDeletedFromRelationshipsPriorToSave' flag to Adapter that allows one to opt back into the old deleted record from many array behavior (pre emberjs#3539). Known issues: 1. Rolling back a hasMany relationship from the parent side of the relationship does not work (doing the same from the child side works fine). See test that is commented out below as well as the discussion at the end of emberjs#2881#issuecomment-204634262 This was previously emberjs#2881 and is related to emberjs#3698
This commit: 1. Allows one to rollback belongsTo and hasMany relationships. 2. Reintroduces dirtyRecordFor*Change hooks on the adapter that allow one to customize when a record becomes dirty. 3. Added 'removeDeletedFromRelationshipsPriorToSave' flag to Adapter that allows one to opt back into the old deleted record from many array behavior (pre emberjs#3539). Known issues: 1. Rolling back a hasMany relationship from the parent side of the relationship does not work (doing the same from the child side works fine). See test that is commented out below as well as the discussion at the end of emberjs#2881#issuecomment-204634262 This was previously emberjs#2881 and is related to emberjs#3698
This commit: 1. Allows one to rollback belongsTo and hasMany relationships. 2. Reintroduces dirtyRecordFor*Change hooks on the adapter that allow one to customize when a record becomes dirty. 3. Added 'removeDeletedFromRelationshipsPriorToSave' flag to Adapter that allows one to opt back into the old deleted record from many array behavior (pre emberjs#3539). Known issues: 1. Rolling back a hasMany relationship from the parent side of the relationship does not work (doing the same from the child side works fine). See test that is commented out below as well as the discussion at the end of emberjs#2881#issuecomment-204634262 This was previously emberjs#2881 and is related to emberjs#3698
This commit: 1. Allows one to rollback belongsTo and hasMany relationships. 2. Reintroduces dirtyRecordFor*Change hooks on the adapter that allow one to customize when a record becomes dirty. 3. Added 'removeDeletedFromRelationshipsPriorToSave' flag to Adapter that allows one to opt back into the old deleted record from many array behavior (pre emberjs#3539). Known issues: 1. Rolling back a hasMany relationship from the parent side of the relationship does not work (doing the same from the child side works fine). See test that is commented out below as well as the discussion at the end of emberjs#2881#issuecomment-204634262 This was previously emberjs#2881 and is related to emberjs#3698
This commit: 1. Allows one to rollback belongsTo and hasMany relationships. 2. Reintroduces dirtyRecordFor*Change hooks on the adapter that allow one to customize when a record becomes dirty. 3. Added 'removeDeletedFromRelationshipsPriorToSave' flag to Adapter that allows one to opt back into the old deleted record from many array behavior (pre emberjs#3539). Known issues: 1. Rolling back a hasMany relationship from the parent side of the relationship does not work (doing the same from the child side works fine). See test that is commented out below as well as the discussion at the end of emberjs#2881#issuecomment-204634262 This was previously emberjs#2881 and is related to emberjs#3698
This commit: 1. Allows one to rollback belongsTo and hasMany relationships. 2. Reintroduces dirtyRecordFor*Change hooks on the adapter that allow one to customize when a record becomes dirty. 3. Added 'removeDeletedFromRelationshipsPriorToSave' flag to Adapter that allows one to opt back into the old deleted record from many array behavior (pre emberjs#3539). Known issues: 1. Rolling back a hasMany relationship from the parent side of the relationship does not work (doing the same from the child side works fine). See test that is commented out below as well as the discussion at the end of emberjs#2881#issuecomment-204634262 This was previously emberjs#2881 and is related to emberjs#3698
This commit: 1. Allows one to rollback belongsTo and hasMany relationships. 2. Reintroduces dirtyRecordFor*Change hooks on the adapter that allow one to customize when a record becomes dirty. 3. Added 'removeDeletedFromRelationshipsPriorToSave' flag to Adapter that allows one to opt back into the old deleted record from many array behavior (pre emberjs#3539). Known issues: 1. Rolling back a hasMany relationship from the parent side of the relationship does not work (doing the same from the child side works fine). See test that is commented out below as well as the discussion at the end of emberjs#2881#issuecomment-204634262 This was previously emberjs#2881 and is related to emberjs#3698
This commit: 1. Allows one to rollback belongsTo and hasMany relationships. 2. Reintroduces dirtyRecordFor*Change hooks on the adapter that allow one to customize when a record becomes dirty. 3. Added 'removeDeletedFromRelationshipsPriorToSave' flag to Adapter that allows one to opt back into the old deleted record from many array behavior (pre emberjs#3539). 4. Adds bin/build.js to build a standalone version of ember-data. Known issues: 1. Rolling back a hasMany relationship from the parent side of the relationship does not work (doing the same from the child side works fine). See test that is commented out below as well as the discussion at the end of emberjs#2881#issuecomment-204634262 This was previously emberjs#2881 and is related to emberjs#3698
This commit: 1. Allows one to rollback belongsTo and hasMany relationships. 2. Reintroduces dirtyRecordFor*Change hooks on the adapter that allow one to customize when a record becomes dirty. 3. Added 'removeDeletedFromRelationshipsPriorToSave' flag to Adapter that allows one to opt back into the old deleted record from many array behavior (pre emberjs#3539). 4. Adds bin/build.js to build a standalone version of ember-data. Known issues: 1. Rolling back a hasMany relationship from the parent side of the relationship does not work (doing the same from the child side works fine). See test that is commented out below as well as the discussion at the end of emberjs#2881#issuecomment-204634262 This was previously emberjs#2881 and is related to emberjs#3698
This commit: 1. Allows one to rollback belongsTo and hasMany relationships. 2. Added 'shouldRemoveDeletedFromRelationshipsPriorToSave' flag to Adapter that allows one to opt back into the old deleted record from many array behavior (pre emberjs#3539). 3. Adds bin/build.js to build a standalone version of ember-data. Known issues: 1. Rolling back a hasMany relationship from the parent side of that relationship does not work (doing the same from the child side works fine). See test that is commented out below as well as the discussion at the end of emberjs#2881#issuecomment-204634262 This was previously emberjs#2881 and is related to emberjs#3698
This commit: 1. Allows one to rollback belongsTo and hasMany relationships. 2. Added 'shouldRemoveDeletedFromRelationshipsPriorToSave' flag to Adapter that allows one to opt back into the old deleted record from many array behavior (pre emberjs#3539). 3. Adds bin/build.js to build a standalone version of ember-data. Known issues: 1. Rolling back a hasMany relationship from the parent side of that relationship does not work (doing the same from the child side works fine). See test that is commented out below as well as the discussion at the end of emberjs#2881#issuecomment-204634262 This was previously emberjs#2881 and is related to emberjs#3698
This commit: 1. Allows one to rollback belongsTo and hasMany relationships. 2. Added 'shouldRemoveDeletedFromRelationshipsPriorToSave' flag to Adapter that allows one to opt back into the old deleted record from many array behavior (pre emberjs#3539). 3. Adds bin/build.js to build a standalone version of ember-data. Known issues: 1. Rolling back a hasMany relationship from the parent side of that relationship does not work (doing the same from the child side works fine). See test that is commented out below as well as the discussion at the end of emberjs#2881#issuecomment-204634262 This was previously emberjs#2881 and is related to emberjs#3698
This commit: 1. Allows one to rollback belongsTo and hasMany relationships. 2. Added 'shouldRemoveDeletedFromRelationshipsPriorToSave' flag to Adapter that allows one to opt back into the old deleted record from many array behavior (pre emberjs#3539). 3. Adds bin/build.js to build a standalone version of ember-data. Known issues: 1. Rolling back a hasMany relationship from the parent side of that relationship does not work (doing the same from the child side works fine). See test that is commented out below as well as the discussion at the end of emberjs#2881#issuecomment-204634262 This was previously emberjs#2881 and is related to emberjs#3698
This commit: 1. Allows one to rollback belongsTo and hasMany relationships. 2. Added 'shouldRemoveDeletedFromRelationshipsPriorToSave' flag to Adapter that allows one to opt back into the old deleted record from many array behavior (pre emberjs#3539). 3. Adds bin/build.js to build a standalone version of ember-data. Known issues: 1. Rolling back a hasMany relationship from the parent side of that relationship does not work (doing the same from the child side works fine). See test that is commented out below as well as the discussion at the end of emberjs#2881#issuecomment-204634262 This was previously emberjs#2881 and is related to emberjs#3698
This commit allows relationships to be rolledback and also reintroduces
dirtyRecordFor*Change
hooks on the adapter.