Skip to content

Commit

Permalink
🎨 register events in base model (#7560)
Browse files Browse the repository at this point in the history
refs #7432

- all models implemented it's own initialize fn to register events
- we can register all events in the base model
- important: we only listen on the event, if the model has defined a hook for it
- this is just a small clean up PR
- register more bookshelf events
  • Loading branch information
kirrg001 authored and ErisDS committed Oct 14, 2016
1 parent 4411f82 commit 8cd5d9f
Show file tree
Hide file tree
Showing 9 changed files with 167 additions and 172 deletions.
8 changes: 2 additions & 6 deletions core/server/models/accesstoken.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,8 @@ Accesstoken = Basetoken.extend({
events.emit('token' + '.' + event, this);
},

initialize: function initialize() {
ghostBookshelf.Model.prototype.initialize.apply(this, arguments);

this.on('created', function onCreated(model) {
model.emitChange('added');
});
onCreated: function onCreated(model) {
model.emitChange('added');
}
});

Expand Down
4 changes: 2 additions & 2 deletions core/server/models/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ var ghostBookshelf = require('./base'),
App = ghostBookshelf.Model.extend({
tableName: 'apps',

saving: function saving(newPage, attr, options) {
onSaving: function onSaving(newPage, attr, options) {
/*jshint unused:false*/
var self = this;

ghostBookshelf.Model.prototype.saving.apply(this, arguments);
ghostBookshelf.Model.prototype.onSaving.apply(this, arguments);

if (this.hasChanged('slug') || !this.get('slug')) {
// Pass the new slug through the generator to strip illegal characters, detect duplicates
Expand Down
30 changes: 23 additions & 7 deletions core/server/models/base/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,25 +79,41 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
this.include = _.clone(options.include);
}

this.on('creating', this.creating, this);
this.on('saving', function onSaving(model, attributes, options) {
return Promise.resolve(self.saving(model, attributes, options)).then(function then() {
return self.validate(model, attributes, options);
['fetching', 'fetched', 'creating', 'created', 'updating', 'updated', 'destroying', 'destroyed', 'saved']
.forEach(function (eventName) {
var functionName = 'on' + eventName[0].toUpperCase() + eventName.slice(1);

if (!self[functionName]) {
return;
}

self.on(eventName, function eventTriggered() {
return this[functionName].apply(this, arguments);
});
});

this.on('saving', function onSaving() {
var self = this,
args = arguments;

return Promise.resolve(self.onSaving.apply(self, args))
.then(function validated() {
return Promise.resolve(self.onValidate.apply(self, args));
});
});
},

validate: function validate() {
onValidate: function onValidate() {
return validation.validateSchema(this.tableName, this.toJSON());
},

creating: function creating(newObj, attr, options) {
onCreating: function onCreating(newObj, attr, options) {
if (!this.get('created_by')) {
this.set('created_by', this.contextUser(options));
}
},

saving: function saving(newObj, attr, options) {
onSaving: function onSaving(newObj, attr, options) {
// Remove any properties which don't belong on the model
this.attributes = this.pick(this.permittedAttributes());
// Store the previous attributes so we can tell what was updated later
Expand Down
7 changes: 2 additions & 5 deletions core/server/models/base/token.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,11 @@ Basetoken = ghostBookshelf.Model.extend({

// override for base function since we don't have
// a created_by field for sessions
creating: function creating(newObj, attr, options) {
/*jshint unused:false*/
},
onCreating: function onCreating() {},

// override for base function since we don't have
// a updated_by field for sessions
saving: function saving(newObj, attr, options) {
/*jshint unused:false*/
onSaving: function onSaving() {
// Remove any properties which don't belong on the model
this.attributes = this.pick(this.permittedAttributes());
}
Expand Down
157 changes: 75 additions & 82 deletions core/server/models/post.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,113 +38,106 @@ Post = ghostBookshelf.Model.extend({
};
},

initialize: function initialize() {
var self = this;
onSaved: function onSaved(model, response, options) {
return this.updateTags(model, response, options);
},

ghostBookshelf.Model.prototype.initialize.apply(this, arguments);
onCreated: function onCreated(model) {
var status = model.get('status');
model.emitChange('added');

this.on('saved', function onSaved(model, response, options) {
return self.updateTags(model, response, options);
});
if (['published', 'scheduled'].indexOf(status) !== -1) {
model.emitChange(status);
}
},

this.on('created', function onCreated(model) {
var status = model.get('status');
onUpdated: function onUpdated(model) {
model.statusChanging = model.get('status') !== model.updated('status');
model.isPublished = model.get('status') === 'published';
model.isScheduled = model.get('status') === 'scheduled';
model.wasPublished = model.updated('status') === 'published';
model.wasScheduled = model.updated('status') === 'scheduled';
model.resourceTypeChanging = model.get('page') !== model.updated('page');
model.publishedAtHasChanged = model.hasDateChanged('published_at');
model.needsReschedule = model.publishedAtHasChanged && model.isScheduled;

// Handle added and deleted for post -> page or page -> post
if (model.resourceTypeChanging) {
if (model.wasPublished) {
model.emitChange('unpublished', true);
}

if (model.wasScheduled) {
model.emitChange('unscheduled', true);
}

model.emitChange('deleted', true);
model.emitChange('added');

if (['published', 'scheduled'].indexOf(status) !== -1) {
model.emitChange(status);
if (model.isPublished) {
model.emitChange('published');
}
});

this.on('updated', function onUpdated(model) {
model.statusChanging = model.get('status') !== model.updated('status');
model.isPublished = model.get('status') === 'published';
model.isScheduled = model.get('status') === 'scheduled';
model.wasPublished = model.updated('status') === 'published';
model.wasScheduled = model.updated('status') === 'scheduled';
model.resourceTypeChanging = model.get('page') !== model.updated('page');
model.publishedAtHasChanged = model.hasDateChanged('published_at');
model.needsReschedule = model.publishedAtHasChanged && model.isScheduled;

// Handle added and deleted for post -> page or page -> post
if (model.resourceTypeChanging) {
if (model.isScheduled) {
model.emitChange('scheduled');
}
} else {
if (model.statusChanging) {
// CASE: was published before and is now e.q. draft or scheduled
if (model.wasPublished) {
model.emitChange('unpublished', true);
model.emitChange('unpublished');
}

if (model.wasScheduled) {
model.emitChange('unscheduled', true);
}

model.emitChange('deleted', true);
model.emitChange('added');

// CASE: was draft or scheduled before and is now e.q. published
if (model.isPublished) {
model.emitChange('published');
}

// CASE: was draft or published before and is now e.q. scheduled
if (model.isScheduled) {
model.emitChange('scheduled');
}
} else {
if (model.statusChanging) {
// CASE: was published before and is now e.q. draft or scheduled
if (model.wasPublished) {
model.emitChange('unpublished');
}

// CASE: was draft or scheduled before and is now e.q. published
if (model.isPublished) {
model.emitChange('published');
}

// CASE: was draft or published before and is now e.q. scheduled
if (model.isScheduled) {
model.emitChange('scheduled');
}

// CASE: from scheduled to something
if (model.wasScheduled && !model.isScheduled && !model.isPublished) {
model.emitChange('unscheduled');
}
} else {
if (model.isPublished) {
model.emitChange('published.edited');
}

if (model.needsReschedule) {
model.emitChange('rescheduled');
}
// CASE: from scheduled to something
if (model.wasScheduled && !model.isScheduled && !model.isPublished) {
model.emitChange('unscheduled');
}
} else {
if (model.isPublished) {
model.emitChange('published.edited');
}

// Fire edited if this wasn't a change between resourceType
model.emitChange('edited');
if (model.needsReschedule) {
model.emitChange('rescheduled');
}
}
});

this.on('destroying', function (model, options) {
return model.load('tags', options)
.then(function (response) {
if (!response.related || !response.related('tags') || !response.related('tags').length) {
return;
}
// Fire edited if this wasn't a change between resourceType
model.emitChange('edited');
}
},

return Promise.mapSeries(response.related('tags').models, function (tag) {
return baseUtils.tagUpdate.detachTagFromPost(model, tag, options)();
});
})
.then(function () {
if (model.previous('status') === 'published') {
model.emitChange('unpublished');
}
onDestroying: function onDestroying(model, options) {
return model.load('tags', options)
.then(function (response) {
if (!response.related || !response.related('tags') || !response.related('tags').length) {
return;
}

model.emitChange('deleted');
return Promise.mapSeries(response.related('tags').models, function (tag) {
return baseUtils.tagUpdate.detachTagFromPost(model, tag, options)();
});
});
})
.then(function () {
if (model.previous('status') === 'published') {
model.emitChange('unpublished');
}

model.emitChange('deleted');
});
},

saving: function saving(model, attr, options) {
onSaving: function onSaving(model, attr, options) {
options = options || {};

var self = this,
Expand Down Expand Up @@ -207,7 +200,7 @@ Post = ghostBookshelf.Model.extend({
this.tagsToSave = tags;
}

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

if (mobiledoc) {
this.set('html', converter.render(JSON.parse(mobiledoc)).result);
Expand Down Expand Up @@ -267,15 +260,15 @@ Post = ghostBookshelf.Model.extend({
}
},

creating: function creating(model, attr, options) {
onCreating: function onCreating(model, attr, options) {
options = options || {};

// set any dynamic default properties
if (!this.get('author_id')) {
this.set('author_id', this.contextUser(options));
}

ghostBookshelf.Model.prototype.creating.call(this, model, attr, options);
ghostBookshelf.Model.prototype.onCreating.call(this, model, attr, options);
},

/**
Expand Down
28 changes: 13 additions & 15 deletions core/server/models/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,24 +55,22 @@ Settings = ghostBookshelf.Model.extend({
events.emit('settings' + '.' + event, this);
},

initialize: function initialize() {
ghostBookshelf.Model.prototype.initialize.apply(this, arguments);
onDestroyed: function onDestroyed(model) {
model.emitChange('deleted');
model.emitChange(model.attributes.key + '.' + 'deleted');
},

this.on('created', function (model) {
model.emitChange('added');
model.emitChange(model.attributes.key + '.' + 'added');
});
this.on('updated', function (model) {
model.emitChange('edited');
model.emitChange(model.attributes.key + '.' + 'edited');
});
this.on('destroyed', function (model) {
model.emitChange('deleted');
model.emitChange(model.attributes.key + '.' + 'deleted');
});
onCreated: function onCreated(model) {
model.emitChange('added');
model.emitChange(model.attributes.key + '.' + 'added');
},

onUpdated: function onUpdated(model) {
model.emitChange('edited');
model.emitChange(model.attributes.key + '.' + 'edited');
},

validate: function validate() {
onValidate: function onValidate() {
var self = this,
setting = this.toJSON();

Expand Down
23 changes: 12 additions & 11 deletions core/server/models/subscriber.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,24 @@ Subscriber = ghostBookshelf.Model.extend({
emitChange: function emitChange(event) {
events.emit('subscriber' + '.' + event, this);
},

defaults: function defaults() {
return {
uuid: uuid.v4(),
status: 'subscribed'
};
},
initialize: function initialize() {
ghostBookshelf.Model.prototype.initialize.apply(this, arguments);
this.on('created', function onCreated(model) {
model.emitChange('added');
});
this.on('updated', function onUpdated(model) {
model.emitChange('edited');
});
this.on('destroyed', function onDestroyed(model) {
model.emitChange('deleted');
});

onCreated: function onCreated(model) {
model.emitChange('added');
},

onUpdated: function onUpdated(model) {
model.emitChange('edited');
},

onDestroyed: function onDestroyed(model) {
model.emitChange('deleted');
}
}, {

Expand Down
Loading

0 comments on commit 8cd5d9f

Please sign in to comment.