mirror of
https://github.com/codeninjasllc/discourse.git
synced 2025-02-25 07:54:11 -05:00
Move identity map into the store, shouldn't have been in the adapter
This commit is contained in:
parent
ecb553af3f
commit
7c25efc095
5 changed files with 122 additions and 88 deletions
|
@ -1,35 +1,8 @@
|
||||||
const ADMIN_MODELS = ['plugin'];
|
const ADMIN_MODELS = ['plugin'];
|
||||||
|
|
||||||
const _identityMap = {};
|
|
||||||
|
|
||||||
const RestModel = Ember.Object.extend({
|
|
||||||
update(attrs) {
|
|
||||||
const self = this,
|
|
||||||
type = this.get('__type');
|
|
||||||
return this.store.update(type, this.get('id'), attrs).then(function(result) {
|
|
||||||
if (result && result[type]) {
|
|
||||||
Object.keys(result).forEach(function(k) {
|
|
||||||
attrs[k] = result[k];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
self.setProperties(attrs);
|
|
||||||
return result;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
destroyRecord() {
|
|
||||||
const type = this.get('__type');
|
|
||||||
return this.store.destroyRecord(type, this.get('id'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
export default Ember.Object.extend({
|
export default Ember.Object.extend({
|
||||||
serverName(type) {
|
|
||||||
return Ember.String.underscore(type + 's');
|
|
||||||
},
|
|
||||||
|
|
||||||
pathFor(type, id) {
|
pathFor(type, id) {
|
||||||
let path = "/" + this.serverName(type);
|
let path = "/" + Ember.String.underscore(type + 's');
|
||||||
|
|
||||||
if (ADMIN_MODELS.indexOf(type) !== -1) { path = "/admin/" + path; }
|
if (ADMIN_MODELS.indexOf(type) !== -1) { path = "/admin/" + path; }
|
||||||
if (id) { path += "/" + id; }
|
if (id) { path += "/" + id; }
|
||||||
|
@ -37,66 +10,22 @@ export default Ember.Object.extend({
|
||||||
return path;
|
return path;
|
||||||
},
|
},
|
||||||
|
|
||||||
findAll(type) {
|
findAll(store, type) {
|
||||||
var self = this;
|
return Discourse.ajax(this.pathFor(type));
|
||||||
return Discourse.ajax(this.pathFor(type)).then(function(result) {
|
|
||||||
return result[self.serverName(type)].map(obj => self._hydrate(type, obj));
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
find(type, id) {
|
find(store, type, id) {
|
||||||
var self = this;
|
return Discourse.ajax(this.pathFor(type, id));
|
||||||
return Discourse.ajax(this.pathFor(type, id)).then(function(result) {
|
|
||||||
return self._hydrate(type, result[Ember.String.underscore(type)]);
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
update(type, id, attrs) {
|
update(store, type, id, attrs) {
|
||||||
const data = {};
|
const data = {};
|
||||||
data[Ember.String.underscore(type)] = attrs;
|
data[Ember.String.underscore(type)] = attrs;
|
||||||
|
return Discourse.ajax(this.pathFor(type, id), { method: 'PUT', data });
|
||||||
return Discourse.ajax(this.pathFor(type, id), { method: 'PUT', data }).then(function (result) {
|
|
||||||
if (result && result[type] && result[type].id) {
|
|
||||||
const oldRecord = _identityMap[type][id];
|
|
||||||
delete _identityMap[type][id];
|
|
||||||
_identityMap[type][result[type].id] = oldRecord;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
destroyRecord(type, id) {
|
destroyRecord(store, type, record) {
|
||||||
return Discourse.ajax(this.pathFor(type, id), { method: 'DELETE' }).then(function(result) {
|
return Discourse.ajax(this.pathFor(type, record.get('id')), { method: 'DELETE' });
|
||||||
const forType = _identityMap[type];
|
|
||||||
if (forType) { delete forType[id]; }
|
|
||||||
return result;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
createRecord(type, attrs) {
|
|
||||||
return this._hydrate(type, attrs);
|
|
||||||
},
|
|
||||||
|
|
||||||
_hydrate(type, obj) {
|
|
||||||
if (!obj) { throw "Can't hydrate " + type + " of `null`"; }
|
|
||||||
if (!obj.id) { throw "Can't hydrate " + type + " without an `id`"; }
|
|
||||||
|
|
||||||
_identityMap[type] = _identityMap[type] || {};
|
|
||||||
|
|
||||||
const existing = _identityMap[type][obj.id];
|
|
||||||
if (existing) {
|
|
||||||
delete obj.id;
|
|
||||||
existing.setProperties(obj);
|
|
||||||
return existing;
|
|
||||||
}
|
|
||||||
|
|
||||||
obj.store = this;
|
|
||||||
obj.__type = type;
|
|
||||||
|
|
||||||
const klass = this.container.lookupFactory('model:' + type) || RestModel;
|
|
||||||
const model = klass.create(obj);
|
|
||||||
_identityMap[type][obj.id] = model;
|
|
||||||
return model;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,21 +1,87 @@
|
||||||
|
const _identityMap = {};
|
||||||
|
|
||||||
|
const RestModel = Ember.Object.extend({
|
||||||
|
update(attrs) {
|
||||||
|
const self = this,
|
||||||
|
type = this.get('__type');
|
||||||
|
return this.store.update(type, this.get('id'), attrs).then(function(result) {
|
||||||
|
if (result && result[type]) {
|
||||||
|
Object.keys(result).forEach(function(k) {
|
||||||
|
attrs[k] = result[k];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
self.setProperties(attrs);
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
destroyRecord() {
|
||||||
|
const type = this.get('__type');
|
||||||
|
return this.store.destroyRecord(type, this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
export default Ember.Object.extend({
|
export default Ember.Object.extend({
|
||||||
findAll(type) {
|
findAll(type) {
|
||||||
const adapter = this.container.lookup('adapter:' + type) || this.container.lookup('adapter:rest');
|
const adapter = this.container.lookup('adapter:' + type) || this.container.lookup('adapter:rest');
|
||||||
return adapter.findAll(type);
|
const self = this;
|
||||||
|
return adapter.findAll(this, type).then(function(result) {
|
||||||
|
return result[Ember.String.underscore(type + 's')].map(obj => self._hydrate(type, obj));
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
find(type, id) {
|
find(type, id) {
|
||||||
const adapter = this.container.lookup('adapter:' + type) || this.container.lookup('adapter:rest');
|
const adapter = this.container.lookup('adapter:' + type) || this.container.lookup('adapter:rest');
|
||||||
return adapter.find(type, id);
|
const self = this;
|
||||||
|
return adapter.find(this, type, id).then(function(result) {
|
||||||
|
return self._hydrate(type, result[Ember.String.underscore(type)]);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
update(type, id, attrs) {
|
||||||
|
const adapter = this.container.lookup('adapter:' + type) || this.container.lookup('adapter:rest');
|
||||||
|
return adapter.update(this, type, id, attrs, function(result) {
|
||||||
|
if (result && result[type] && result[type].id) {
|
||||||
|
const oldRecord = _identityMap[type][id];
|
||||||
|
delete _identityMap[type][id];
|
||||||
|
_identityMap[type][result[type].id] = oldRecord;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
createRecord(type, attrs) {
|
createRecord(type, attrs) {
|
||||||
const adapter = this.container.lookup('adapter:' + type) || this.container.lookup('adapter:rest');
|
return this._hydrate(type, attrs);
|
||||||
return adapter.createRecord(type, attrs);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
destroyRecord(type, id) {
|
destroyRecord(type, record) {
|
||||||
const adapter = this.container.lookup('adapter:' + type) || this.container.lookup('adapter:rest');
|
const adapter = this.container.lookup('adapter:' + type) || this.container.lookup('adapter:rest');
|
||||||
return adapter.destroyRecord(type, id);
|
return adapter.destroyRecord(this, type, record).then(function(result) {
|
||||||
|
const forType = _identityMap[type];
|
||||||
|
if (forType) { delete forType[record.get('id')]; }
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_hydrate(type, obj) {
|
||||||
|
if (!obj) { throw "Can't hydrate " + type + " of `null`"; }
|
||||||
|
if (!obj.id) { throw "Can't hydrate " + type + " without an `id`"; }
|
||||||
|
|
||||||
|
_identityMap[type] = _identityMap[type] || {};
|
||||||
|
|
||||||
|
const existing = _identityMap[type][obj.id];
|
||||||
|
if (existing) {
|
||||||
|
delete obj.id;
|
||||||
|
existing.setProperties(obj);
|
||||||
|
return existing;
|
||||||
|
}
|
||||||
|
|
||||||
|
obj.store = this;
|
||||||
|
obj.__type = type;
|
||||||
|
|
||||||
|
const klass = this.container.lookupFactory('model:' + type) || RestModel;
|
||||||
|
const model = klass.create(obj);
|
||||||
|
_identityMap[type][obj.id] = model;
|
||||||
|
return model;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -99,6 +99,12 @@ export default function() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.put('/widgets/:widget_id', function(request) {
|
||||||
|
const w = _widgets.findBy('id', parseInt(request.params.widget_id));
|
||||||
|
const cloned = JSON.parse(JSON.stringify(w));
|
||||||
|
return response({ widget: cloned });
|
||||||
|
});
|
||||||
|
|
||||||
this.get('/widgets', function() {
|
this.get('/widgets', function() {
|
||||||
return response({ widgets: _widgets });
|
return response({ widgets: _widgets });
|
||||||
});
|
});
|
||||||
|
|
24
test/javascripts/models/rest-model-test.js.es6
Normal file
24
test/javascripts/models/rest-model-test.js.es6
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
module('rest-model');
|
||||||
|
|
||||||
|
import createStore from 'helpers/create-store';
|
||||||
|
|
||||||
|
test('update', function() {
|
||||||
|
const store = createStore();
|
||||||
|
|
||||||
|
store.find('widget', 123).then(function(widget) {
|
||||||
|
equal(widget.get('name'), 'Trout Lure');
|
||||||
|
widget.update({ name: 'new name' }).then(function() {
|
||||||
|
equal(widget.get('name'), 'new name');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('destroyRecord', function() {
|
||||||
|
const store = createStore();
|
||||||
|
store.find('widget', 123).then(function(widget) {
|
||||||
|
widget.destroyRecord().then(function(result) {
|
||||||
|
ok(result);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
@ -23,6 +23,13 @@ test('find', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('update', function() {
|
||||||
|
const store = createStore();
|
||||||
|
store.update('widget', 123, {name: 'hello'}).then(function(result) {
|
||||||
|
ok(result);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
test('findAll', function() {
|
test('findAll', function() {
|
||||||
const store = createStore();
|
const store = createStore();
|
||||||
store.findAll('widget').then(function(result) {
|
store.findAll('widget').then(function(result) {
|
||||||
|
@ -34,7 +41,9 @@ test('findAll', function() {
|
||||||
|
|
||||||
test('destroyRecord', function() {
|
test('destroyRecord', function() {
|
||||||
const store = createStore();
|
const store = createStore();
|
||||||
store.destroyRecord('widget', 124).then(function(result) {
|
store.find('widget', 123).then(function(w) {
|
||||||
ok(result);
|
store.destroyRecord('widget', w).then(function(result) {
|
||||||
|
ok(result);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue