Skip to content

Instantly share code, notes, and snippets.

@joelalejandro
Last active August 29, 2015 14:26
Show Gist options
  • Save joelalejandro/22bd25bbf53d28e2643a to your computer and use it in GitHub Desktop.
Save joelalejandro/22bd25bbf53d28e2643a to your computer and use it in GitHub Desktop.
Ember Data model replication
/**
* @package ReplicableMixin
* @author Joel A. Villarreal Bertoldi
* @version 0.0.1
* @license MIT
*
* Allows replicating a model with relationships to the database.
*
* Usage:
*
* model.replicate().then(function(copiedModel) {
* //do something!
* });
*
* To configure it, import and apply Replicable mixin:
*
* ´´´js
* import Replicable from 'replicable';
* import DS from 'ember-data';
*
* export default DS.Model.extend(Replicable, {
* //...
* });
* ´´´
*
* To prevent an attribute or relationship from being copied:
*
* ´´´js
* export default DS.Model.extend(Replicable, {
* name: DS.attr('string'),
* nonCopyableData: DS.attr('string', { copy: false }),
* nonCopyableAssets: DS.hasMany('asset', { async: true, copy: false }),
* });
* ´´´
*
* To transform an attribute before copying it:
*
* ´´´js
* export default DS.Model.extend(Replicable, {
* name: DS.attr('string', {
* copyTransform: function() {
* return this.get('name') + ' - Copy';
* }
* })
* });
* ´´´
*
*/
import Ember from 'ember';
export default Ember.Mixin.create({
replicate: function() {
var model = this.store.createRecord(this.constructor.typeKey),
_this = this;
model.beginPropertyChanges();
var attrIterator = function(name, member) {
if (member.options.hasOwnProperty('copy')) {
if (member.options.copy === false) {
return;
}
}
if (typeof member.options.copyTransform === 'function') {
model.set(name, member.options.copyTransform.call(_this));
} else {
model.set(name, _this.get(name));
}
};
var relIterator = function(name, member) {
if (member.options.hasOwnProperty('copy')) {
if (member.options.copy === false) {
return;
}
}
if (member.kind === 'hasMany') {
model.get(name).pushObjects(_this.get(name));
} else {
model.set(name, _this.get(name));
}
};
this.eachAttribute(attrIterator);
this.eachRelationship(relIterator);
model.endPropertyChanges();
return new Ember.RSVP.Promise(function(resolve, reject) {
model.save().then(function() {
resolve(model);
}).catch(reject);
});
}
});
/**
* @package ReplicableWithFragmentsMixin
* @author Joel A. Villarreal Bertoldi
* @version 0.0.1
* @license MIT
*
* Allows replicating a model with relationships to the database.
* Compatible with Ember Model Fragments
*
* Usage:
*
* model.replicate().then(function(copiedModel) {
* //do something!
* });
*
* To configure it, import and apply Replicable mixin:
*
* ´´´js
* import Replicable from 'replicable';
* import DS from 'ember-data';
*
* export default DS.Model.extend(Replicable, {
* //...
* });
* ´´´
*
* To prevent an attribute or relationship from being copied:
*
* ´´´js
* export default DS.Model.extend(Replicable, {
* name: DS.attr('string'),
* nonCopyableData: DS.attr('string', { copy: false }),
* nonCopyableAssets: DS.hasMany('asset', { async: true, copy: false }),
* nonCopyableFragments: DS.hasManyFragments('fragment', { copy: false })
* });
* ´´´
*
* To transform an attribute before copying it:
*
* ´´´js
* export default DS.Model.extend(Replicable, {
* name: DS.attr('string', {
* copyTransform: function() {
* return this.get('name') + ' - Copy';
* }
* })
* });
* ´´´
*
*/
import Ember from 'ember';
export default Ember.Mixin.create({
replicate: function() {
var model = this.store.createRecord(this.constructor.typeKey),
_this = this;
model.beginPropertyChanges();
var attrIterator = function(name, member) {
if (member.options.hasOwnProperty('copy')) {
if (member.options.copy === false) {
return;
}
}
if (typeof member.options.copyTransform === 'function') {
model.set(name, member.options.copyTransform.call(_this));
} else {
if (!!_this._fragments) {
if (!!_this._fragments[name]) {
_this.get(name).forEach(function(fragment) {
model.get(name).pushObject(fragment.copy());
});
} else {
model.set(name, _this.get(name));
}
} else {
model.set(name, _this.get(name));
}
}
};
var relIterator = function(name, member) {
if (member.options.hasOwnProperty('copy')) {
if (member.options.copy === false) {
return;
}
}
if (member.kind === 'hasMany') {
model.get(name).pushObjects(_this.get(name));
} else {
model.set(name, _this.get(name));
}
};
this.eachAttribute(attrIterator);
this.eachRelationship(relIterator);
model.endPropertyChanges();
return new Ember.RSVP.Promise(function(resolve, reject) {
model.save().then(function() {
resolve(model);
}).catch(reject);
});
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment