Last active
October 13, 2016 08:39
-
-
Save GeoffreyBooth/cc0e7db6696649435a2a to your computer and use it in GitHub Desktop.
Ember.js rollback relationships, including deletions of child objects
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# RollbackAttributes should also rollback relationships | |
# Based on http://stackoverflow.com/a/27184207/223225 and https://github.com/emberjs/rfcs/pull/21#issuecomment-135134132 | |
DS.Model.reopen | |
rollbackAttributes: -> | |
@_super() | |
@rollbackRelationships() | |
cacheOriginalRelations: -> | |
# Save original relations values to @originalRelations | |
@set 'originalRelations', {} | |
# The values of those relations are intially null, even with async: false; so do findRecord to get the complete record | |
@store.findRecord(@constructor.modelName, @id).then (record) => | |
record.eachRelationship (key, relationship) => | |
if relationship.kind is 'belongsTo' | |
@set "originalRelations.#{key}", record.get(key) | |
if relationship.kind is 'hasMany' | |
@set "originalRelations.#{key}", record.get(key).toArray() | |
ready: -> | |
@cacheOriginalRelations() | |
onReloading: (-> | |
unless @get('isReloading') | |
@cacheOriginalRelations() | |
).observes('isReloading') | |
rollbackRelationships: -> | |
return unless @originalRelations? | |
Object.keys(@originalRelations).forEach (key) => | |
# For each relation, set the key to the original value (another record or array of records) | |
if Ember.isArray(@get(key)) # Careful, as Ember.typeOf for ArrayProxy is 'instance' | |
@originalRelations[key].invoke 'rollbackAttributes' # Important! Do this BEFORE setting the value, so undo any possible deletions | |
@get(key).setObjects @originalRelations[key] | |
if Ember.typeOf(@get(key)) is 'instance' | |
@originalRelations[key].rollbackAttributes() if @originalRelations[key].rollbackAttributes? # Important! Do this BEFORE setting the value, so undo any possible deletions | |
@set key, @originalRelations[key] | |
else if Ember.typeOf(@get(key)) is 'null' | |
@set key, @originalRelations[key] | |
isDeepDirty: -> | |
return if @_super('isDirty') or not @originalRelations? | |
Object.keys(@originalRelations).any (key) => | |
if Ember.isArray(@get(key)) | |
return if @get(key).anyBy('isDirty') or @get(key).get('length') isnt @originalRelations[key].length | |
dirty = no | |
@get(key).forEach (item, index) => | |
if item.get('id') isnt @originalRelations[key][index].get('id') | |
dirty = yes | |
return dirty | |
@get(key).get('isDirty') or @get(key).get('id') isnt @originalRelations[key].get('id') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for the code. It was working for the most part, but sadly, it makes each model unit test fail with the following: