We already have beforeCreate and afterUpdate and it seems these hooks can be useful and it's also unexpected to not have parity on this.
114 lines
2.6 KiB
JavaScript
114 lines
2.6 KiB
JavaScript
import { warn } from "@ember/debug";
|
|
import { equal } from "@ember/object/computed";
|
|
import EmberObject from "@ember/object";
|
|
import { Promise } from "rsvp";
|
|
|
|
const RestModel = EmberObject.extend({
|
|
isNew: equal("__state", "new"),
|
|
isCreated: equal("__state", "created"),
|
|
isSaving: false,
|
|
|
|
beforeCreate() {},
|
|
afterCreate() {},
|
|
|
|
beforeUpdate() {},
|
|
afterUpdate() {},
|
|
|
|
update(props) {
|
|
if (this.isSaving) {
|
|
return Promise.reject();
|
|
}
|
|
|
|
props = props || this.updateProperties();
|
|
|
|
this.beforeUpdate(props);
|
|
|
|
this.set("isSaving", true);
|
|
return this.store
|
|
.update(this.__type, this.id, props)
|
|
.then(res => {
|
|
const payload = this.__munge(res.payload || res.responseJson);
|
|
|
|
if (payload.success === "OK") {
|
|
warn("An update call should return the updated attributes", {
|
|
id: "discourse.rest-model.update-attributes"
|
|
});
|
|
res = props;
|
|
}
|
|
|
|
this.setProperties(payload);
|
|
this.afterUpdate(res);
|
|
res.target = this;
|
|
return res;
|
|
})
|
|
.finally(() => this.set("isSaving", false));
|
|
},
|
|
|
|
_saveNew(props) {
|
|
if (this.isSaving) {
|
|
return Promise.reject();
|
|
}
|
|
|
|
props = props || this.createProperties();
|
|
|
|
this.beforeCreate(props);
|
|
|
|
const adapter = this.store.adapterFor(this.__type);
|
|
|
|
this.set("isSaving", true);
|
|
return adapter
|
|
.createRecord(this.store, this.__type, props)
|
|
.then(res => {
|
|
if (!res) {
|
|
throw new Error("Received no data back from createRecord");
|
|
}
|
|
|
|
// We can get a response back without properties, for example
|
|
// when a post is queued.
|
|
if (res.payload) {
|
|
this.setProperties(this.__munge(res.payload));
|
|
this.set("__state", "created");
|
|
}
|
|
|
|
this.afterCreate(res);
|
|
res.target = this;
|
|
return res;
|
|
})
|
|
.finally(() => this.set("isSaving", false));
|
|
},
|
|
|
|
createProperties() {
|
|
throw new Error(
|
|
"You must overwrite `createProperties()` before saving a record"
|
|
);
|
|
},
|
|
|
|
save(props) {
|
|
return this.isNew ? this._saveNew(props) : this.update(props);
|
|
},
|
|
|
|
destroyRecord() {
|
|
return this.store.destroyRecord(this.__type, this);
|
|
}
|
|
});
|
|
|
|
RestModel.reopenClass({
|
|
// Overwrite and JSON will be passed through here before `create` and `update`
|
|
munge(json) {
|
|
return json;
|
|
},
|
|
|
|
create(args) {
|
|
args = args || {};
|
|
if (!args.store) {
|
|
const container = Discourse.__container__;
|
|
args.store = container.lookup("service:store");
|
|
}
|
|
|
|
args.__munge = this.munge;
|
|
return this._super(this.munge(args, args.store));
|
|
}
|
|
});
|
|
|
|
export default RestModel;
|