Skip to content

Instantly share code, notes, and snippets.

@sescobb27
Forked from GeoffreyBooth/Model.coffee
Created September 26, 2016 15:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sescobb27/ed02acc15b1c79e54699bc9adb1553ed to your computer and use it in GitHub Desktop.
Save sescobb27/ed02acc15b1c79e54699bc9adb1553ed to your computer and use it in GitHub Desktop.
Ember.js rollback relationships, including deletions of child objects
# 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')
@sescobb27
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment