2015-04-25 20:58:39 +08:00
|
|
|
export default class Model {
|
|
|
|
constructor(data, store) {
|
|
|
|
this.data = m.prop(data || {});
|
|
|
|
this.freshness = new Date();
|
|
|
|
this.exists = false;
|
|
|
|
this.store = store;
|
|
|
|
}
|
|
|
|
|
2015-07-04 10:54:48 +08:00
|
|
|
id() {
|
|
|
|
return this.data().id;
|
|
|
|
}
|
|
|
|
|
2015-04-25 20:58:39 +08:00
|
|
|
pushData(newData) {
|
|
|
|
var data = this.data();
|
|
|
|
|
|
|
|
for (var i in newData) {
|
2015-07-04 10:54:48 +08:00
|
|
|
if (i === 'relationships') {
|
2015-04-25 20:58:39 +08:00
|
|
|
data[i] = data[i] || {};
|
|
|
|
for (var j in newData[i]) {
|
|
|
|
if (newData[i][j] instanceof Model) {
|
2015-07-04 10:54:48 +08:00
|
|
|
newData[i][j] = {data: {type: newData[i][j].data().type, id: newData[i][j].data().id}};
|
2015-04-25 20:58:39 +08:00
|
|
|
}
|
|
|
|
data[i][j] = newData[i][j];
|
|
|
|
}
|
2015-07-04 10:54:48 +08:00
|
|
|
} else if (i === 'attributes') {
|
|
|
|
data[i] = data[i] || {};
|
|
|
|
for (var j in newData[i]) {
|
|
|
|
data[i][j] = newData[i][j];
|
|
|
|
}
|
2015-04-25 20:58:39 +08:00
|
|
|
} else {
|
|
|
|
data[i] = newData[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this.freshness = new Date();
|
|
|
|
}
|
|
|
|
|
2015-07-04 10:54:48 +08:00
|
|
|
pushAttributes(attributes) {
|
|
|
|
var data = {attributes};
|
|
|
|
|
|
|
|
if (attributes.relationships) {
|
|
|
|
data.relationships = attributes.relationships;
|
|
|
|
delete attributes.relationships;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.pushData(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
save(attributes) {
|
|
|
|
var data = {
|
|
|
|
type: this.data().type,
|
|
|
|
id: this.data().id,
|
|
|
|
attributes
|
|
|
|
};
|
|
|
|
|
|
|
|
if (attributes.relationships) {
|
|
|
|
data.relationships = {};
|
|
|
|
|
|
|
|
for (var i in attributes.relationships) {
|
|
|
|
var model = attributes.relationships[i];
|
|
|
|
var relationshipData = model => {
|
2015-06-12 15:11:13 +08:00
|
|
|
return {type: model.data().type, id: model.data().id};
|
|
|
|
};
|
|
|
|
if (model instanceof Array) {
|
2015-07-04 10:54:48 +08:00
|
|
|
data.relationships[i] = {data: model.map(relationshipData)};
|
2015-06-12 15:11:13 +08:00
|
|
|
} else {
|
2015-07-04 10:54:48 +08:00
|
|
|
data.relationships[i] = {data: relationshipData(model)};
|
2015-06-12 15:11:13 +08:00
|
|
|
}
|
2015-04-25 20:58:39 +08:00
|
|
|
}
|
2015-07-04 10:54:48 +08:00
|
|
|
|
|
|
|
delete attributes.relationships;
|
2015-04-25 20:58:39 +08:00
|
|
|
}
|
|
|
|
|
2015-05-27 14:55:44 +08:00
|
|
|
// clone the relevant parts of the model's old data so that we can revert
|
|
|
|
// back if the save fails
|
|
|
|
var oldData = {};
|
|
|
|
var currentData = this.data();
|
|
|
|
for (var i in data) {
|
2015-07-04 10:54:48 +08:00
|
|
|
if (i === 'relationships') {
|
2015-05-27 14:55:44 +08:00
|
|
|
oldData[i] = oldData[i] || {};
|
2015-05-29 16:47:50 +08:00
|
|
|
for (var j in currentData[i]) {
|
2015-05-27 14:55:44 +08:00
|
|
|
oldData[i][j] = currentData[i][j];
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
oldData[i] = currentData[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-25 20:58:39 +08:00
|
|
|
this.pushData(data);
|
|
|
|
|
2015-05-26 10:13:20 +08:00
|
|
|
return app.request({
|
2015-07-04 10:54:48 +08:00
|
|
|
method: this.exists ? 'PATCH' : 'POST',
|
2015-05-02 07:14:03 +08:00
|
|
|
url: app.config['api_url']+'/'+this.data().type+(this.exists ? '/'+this.data().id : ''),
|
2015-04-25 20:58:39 +08:00
|
|
|
data: {data},
|
|
|
|
background: true,
|
|
|
|
config: app.session.authorize.bind(app.session)
|
|
|
|
}).then(payload => {
|
|
|
|
this.store.data[payload.data.type][payload.data.id] = this;
|
|
|
|
return this.store.pushPayload(payload);
|
2015-05-27 14:55:44 +08:00
|
|
|
}, response => {
|
|
|
|
this.pushData(oldData);
|
|
|
|
throw response;
|
2015-04-25 20:58:39 +08:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
delete() {
|
|
|
|
if (!this.exists) { return; }
|
|
|
|
|
2015-05-26 10:13:20 +08:00
|
|
|
return app.request({
|
2015-04-25 20:58:39 +08:00
|
|
|
method: 'DELETE',
|
2015-05-02 07:14:03 +08:00
|
|
|
url: app.config['api_url']+'/'+this.data().type+'/'+this.data().id,
|
2015-04-25 20:58:39 +08:00
|
|
|
background: true,
|
|
|
|
config: app.session.authorize.bind(app.session)
|
|
|
|
}).then(() => this.exists = false);
|
|
|
|
}
|
|
|
|
|
2015-07-04 10:54:48 +08:00
|
|
|
static attribute(name, transform) {
|
2015-04-25 20:58:39 +08:00
|
|
|
return function() {
|
2015-07-04 10:54:48 +08:00
|
|
|
var data = this.data().attributes[name];
|
2015-05-30 12:28:21 +08:00
|
|
|
return transform ? transform(data) : data;
|
2015-04-25 20:58:39 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-04 10:54:48 +08:00
|
|
|
static hasOne(name) {
|
2015-04-25 20:58:39 +08:00
|
|
|
return function() {
|
2015-05-30 12:28:21 +08:00
|
|
|
var data = this.data();
|
2015-07-04 10:54:48 +08:00
|
|
|
if (data.relationships) {
|
|
|
|
var relationship = data.relationships[name];
|
|
|
|
return relationship && app.store.getById(relationship.data.type, relationship.data.id);
|
2015-05-30 12:28:21 +08:00
|
|
|
}
|
2015-04-25 20:58:39 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-04 10:54:48 +08:00
|
|
|
static hasMany(name) {
|
2015-04-25 20:58:39 +08:00
|
|
|
return function() {
|
2015-05-30 12:28:21 +08:00
|
|
|
var data = this.data();
|
2015-07-04 10:54:48 +08:00
|
|
|
if (data.relationships) {
|
|
|
|
var relationship = this.data().relationships[name];
|
|
|
|
return relationship && relationship.data.map(function(link) {
|
|
|
|
return app.store.getById(link.type, link.id);
|
2015-05-30 12:28:21 +08:00
|
|
|
});
|
|
|
|
}
|
2015-04-25 20:58:39 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-04 10:54:48 +08:00
|
|
|
static transformDate(data) {
|
2015-04-25 20:58:39 +08:00
|
|
|
return data ? new Date(data) : null;
|
|
|
|
}
|
|
|
|
}
|