Skip to content

Commit

Permalink
Added ability to notify and update url service about changes in relat…
Browse files Browse the repository at this point in the history
…ed resources

refs TryGhost#10124
  • Loading branch information
naz committed Jan 5, 2019
1 parent 7e94450 commit 0e4d6c8
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 56 deletions.
4 changes: 4 additions & 0 deletions core/server/models/base/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -1093,6 +1093,10 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
require('../plugins/has-posts').addHasPostsWhere(tableNames[modelName], shouldHavePosts)(query);
}

if (options.id) {
query.where({id: options.id});
}

return query.then((objects) => {
debug('fetched', modelName, filter);

Expand Down
12 changes: 12 additions & 0 deletions core/server/models/post.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,18 @@ Post = ghostBookshelf.Model.extend({
this.set('tags', tagsToSave);
}

model.related('tags').on('detaching', function onDetached(collection, tag) {
model.related('tags').on('detached', function onDetached(detachedCollection, response, options) {
tag.emitChange('edited', options);
});
});

model.related('tags').on('attaching', function onDetached(collection, tags) {
model.related('tags').on('attached', function onDetached(detachedCollection, response, options) {
tags.forEach(tag => tag.emitChange('edited', options));
});
});

ghostBookshelf.Model.prototype.onSaving.call(this, model, attr, options);

// do not allow generated fields to be overridden via the API
Expand Down
87 changes: 31 additions & 56 deletions core/server/services/url/Resources.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,13 @@ class Resources {
});
}

_fetchSingle(resourceConfig, id) {
let modelOptions = _.cloneDeep(resourceConfig.modelOptions);
modelOptions.id = id;

return models.Base.Model.raw_knex.fetchAll(modelOptions);
}

_onResourceAdded(type, model) {
const resourceConfig = _.find(this.resourcesConfig, {type: type});
const exclude = resourceConfig.modelOptions.exclude;
Expand Down Expand Up @@ -183,67 +190,35 @@ class Resources {
_onResourceUpdated(type, model) {
debug('_onResourceUpdated', type);

this.data[type].every((resource) => {
if (resource.data.id === model.id) {
const resourceConfig = _.find(this.resourcesConfig, {type: type});
const exclude = resourceConfig.modelOptions.exclude;
const withRelatedFields = resourceConfig.modelOptions.withRelatedFields;
const obj = _.omit(model.toJSON(), exclude);

if (withRelatedFields) {
_.each(withRelatedFields, (fields, key) => {
if (!obj[key]) {
return;
}

obj[key] = _.map(obj[key], (relation) => {
const relationToReturn = {};

_.each(fields, (field) => {
const fieldSanitized = field.replace(/^\w+./, '');
relationToReturn[fieldSanitized] = relation[fieldSanitized];
});

return relationToReturn;
});
});

const withRelatedPrimary = resourceConfig.modelOptions.withRelatedPrimary;
const resourceConfig = _.find(this.resourcesConfig, {type: type});

if (withRelatedPrimary) {
_.each(withRelatedPrimary, (relation, primaryKey) => {
if (!obj[primaryKey] || !obj[relation]) {
return;
return Promise.resolve()
.then(() => {
return this._fetchSingle(resourceConfig, model.id);
})
.then(([dbResource]) => {
const resource = this.data[type].find(resource => (resource.data.id === model.id));

if (resource && dbResource) {
resource.update(dbResource);

// CASE: pretend it was added
if (!resource.isReserved()) {
this.queue.start({
event: 'added',
action: 'added:' + dbResource.id,
eventData: {
id: dbResource.id,
type: type
}

const targetTagKeys = Object.keys(obj[relation].find((item) => {
return item.id === obj[primaryKey].id;
}));
obj[primaryKey] = _.pick(obj[primaryKey], targetTagKeys);
});
}
} else if (!resource && dbResource) {
this._onResourceAdded(type, model);
} else if (resource && !dbResource) {
this._onResourceRemoved(type, model);
}

resource.update(obj);

// CASE: pretend it was added
if (!resource.isReserved()) {
this.queue.start({
event: 'added',
action: 'added:' + model.id,
eventData: {
id: model.id,
type: type
}
});
}

// break!
return false;
}

return true;
});
});
}

_onResourceRemoved(type, model) {
Expand Down

0 comments on commit 0e4d6c8

Please sign in to comment.