How can I clone an Ember Data record, including relationships?

I found out that I can clone an Ember Data record and copy its attributes, but none of the belongsTo / hasMany are cloned. Can I do this anyway if I don’t know what kind of relationship will be possible based on the existing relationship?

For reference, here is what I got to clone the attributes of an Ember Data record:

 var attributeKeys = oldModel.get('constructor.attributes.keys.list'); var newRecord = this.get('store').createRecord(oldModel.constructor.typeKey); newRecord.setProperties(oldModel.getProperties(attributeKeys)); 
+7
ember-data
source share
4 answers

Several enhancements to Daniel answer that allow override and clear identifier for new entries to be safe. In addition, I prefer not to call save inside the clone method, but leave it to the caller.

 DS.Model.reopen({ clone: function(overrides) { var model = this, attrs = model.toJSON(), class_type = model.constructor; var root = Ember.String.decamelize(class_type.toString().split('.')[1]); /* * Need to replace the belongsTo association ( id ) with the * actual model instance. * * For example if belongsTo association is project, the * json value for project will be: ( project: "project_id_1" ) * and this needs to be converted to ( project: [projectInstance] ) */ this.eachRelationship(function(key, relationship) { if (relationship.kind == 'belongsTo') { attrs[key] = model.get(key); } }); /* * Need to dissociate the new record from the old. */ delete attrs.id; /* * Apply overrides if provided. */ if (Ember.typeOf(overrides) === 'object') { Ember.setProperties(attrs, overrides); } return this.store.createRecord(root, attrs); } }); 
+8
source share

Here is the cloning function I'm using. Takes into account membership in associations.

  DS.Model.reopen({ clone: function() { var model = this, attrs = model.toJSON(), class_type = model.constructor; var root = Ember.String.decamelize(class_type.toString().split('.')[1]); /** * Need to replace the belongsTo association ( id ) with the * actual model instance. * * For example if belongsTo association is project, the * json value for project will be: ( project: "project_id_1" ) * and this needs to be converted to ( project: [projectInstance] ) * */ this.eachRelationship(function(key, relationship){ if (relationship.kind == 'belongsTo') { attrs[key] = model.get(key) } }) return this.store.createRecord(root, attrs).save(); } }) 
+4
source share

There is an addon called ember-cli-copyable , which according to its description:

Deep copies your notes, including their relationships. Mixin is smart enough to allow an unloaded relationship and is tuned to what should be shallow / deeply copied or completely excluded.

0
source share

Here's an easy way to clone your Ember model with relationships. works great.

Create a copy method, for example,

 import Ember from 'ember'; export default Ember.Mixin.create(Ember.Copyable, { copy(deepClone) { var model = this, attrs = model.toJSON(), class_type = model.constructor; var root = Ember.String.decamelize(class_type.toString().split(':')[1]); if(deepClone) { this.eachRelationship(function(key, relationship){ if (relationship.kind == 'belongsTo') { attrs[key] = model.get(key).copy(true); } else if(relationship.kind == 'hasMany' && Ember.isArray(attrs[key])) { attrs[key].splice(0); model.get(key).forEach(function(obj) { attrs[key].addObject(obj.copy(true)); }); } }); } return this.store.createRecord(root, attrs); } }); 

Add mixin to your model,

Note. If you want to clone your child model, you also need to include mixin in the child model

APPLICATION:

  • With ratio: YOURMODEL.copy (true)

  • No relationship: YOURMODEL.copy ()

0
source share

All Articles