I\'ve figured out that I can clone an Ember Data record and copy its Attributes, but none of the belongsTo
/hasMany
relationships are cloned. Can I do t
There's an addon called ember-cli-copyable that according to its description:
Deeply copies your records including their relations. The mixin is smart enough to resolve not loaded relations and is configurable to what should be shallow/deeply copied or excluded entirely.
A few improvements to Daniel's answer that allows providing overrides, and clears the id for new records, to be safe. Also I prefer not to call save
within the clone method, but leave it up 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);
}
});
Here is the simple way to clone your Ember Model with relationships. working fine.
Create a Copyable mixin like,
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 the mixin in your model,
Note: If you want to clone your child model then, you need to include the mixin in child model as well
USAGE:
With relationship : YOURMODEL.copy(true)
Without relationship : YOURMODEL.copy()
Here is a clone function that I use. Takes care of the belongs to 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();
}
})