mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-20 17:32:15 +03:00
8fcb57bd6a
- as per https://github.com/bookshelf/bookshelf/wiki/Migrating-from-0.15.1-to-1.0.0#default-to-require-true-on-modelfetch-and-collectionfetchone, models will now default to `{require:true}` during a fetch, which changes how Bookshelf will respond when a models yields no results - instead of passing a `null` result, it will reject with an error, so we'd need to switch to `.catch`ing everything - our code is set up to handle all these null results and switching style is not currently on the cards so we want to use the existing behaviour for now - to enable this, the `requireFetch` option needs to be added to the model definitions
82 lines
2.8 KiB
JavaScript
82 lines
2.8 KiB
JavaScript
// # Base Model
|
|
// This is the model from which all other Ghost models extend. The model is based on Bookshelf.Model, and provides
|
|
// several basic behaviours such as UUIDs, as well as a set of Data methods for accessing information from the database.
|
|
//
|
|
// The models are internal to Ghost, only the API and some internal functions such as migration and import/export
|
|
// accesses the models directly.
|
|
|
|
// All other parts of Ghost, including the frontend & admin UI are only allowed to access data via the API.
|
|
const moment = require('moment');
|
|
const schema = require('../../data/schema');
|
|
|
|
const ghostBookshelf = require('./bookshelf');
|
|
|
|
// Cache an instance of the base model prototype
|
|
const proto = ghostBookshelf.Model.prototype;
|
|
|
|
// ## ghostBookshelf.Model
|
|
// The Base Model which other Ghost objects will inherit from,
|
|
// including some convenience functions as static properties on the model.
|
|
ghostBookshelf.Model = ghostBookshelf.Model.extend({
|
|
// Bookshelf `hasTimestamps` - handles created_at and updated_at properties
|
|
hasTimestamps: true,
|
|
|
|
requireFetch: false,
|
|
|
|
// https://github.com/bookshelf/bookshelf/commit/a55db61feb8ad5911adb4f8c3b3d2a97a45bd6db
|
|
parsedIdAttribute: function () {
|
|
return false;
|
|
},
|
|
|
|
// Ghost ordering handling, allows to order by permitted attributes by default and can be overriden on specific model level
|
|
orderAttributes: function orderAttributes() {
|
|
return Object.keys(schema.tables[this.tableName])
|
|
.map(key => `${this.tableName}.${key}`)
|
|
.filter(key => key.indexOf('@@') === -1);
|
|
},
|
|
|
|
// Bookshelf `initialize` - declare a constructor-like method for model creation
|
|
initialize: function initialize() {
|
|
this.initializeEvents();
|
|
|
|
// @NOTE: Please keep here. If we don't initialize the parent, bookshelf-relations won't work.
|
|
proto.initialize.call(this);
|
|
},
|
|
|
|
hasDateChanged: function (attr) {
|
|
return moment(this.get(attr)).diff(moment(this.previous(attr))) !== 0;
|
|
},
|
|
|
|
wasChanged() {
|
|
/**
|
|
* @NOTE:
|
|
* Not every model & interaction is currently set up to handle "._changed".
|
|
* e.g. we trigger a manual event for "tag.attached", where as "._changed" is undefined.
|
|
*
|
|
* Keep "true" till we are sure that "._changed" is always a thing.
|
|
*/
|
|
if (!this._changed) {
|
|
return true;
|
|
}
|
|
|
|
if (!Object.keys(this._changed).length) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}, {
|
|
/**
|
|
* @template T
|
|
* @param {(transaction: import('knex').Transaction) => Promise<T>} fn
|
|
*
|
|
* @returns {Promise<T>}
|
|
*/
|
|
transaction(fn) {
|
|
return ghostBookshelf.transaction(fn);
|
|
}
|
|
});
|
|
|
|
// Export ghostBookshelf for use elsewhere
|
|
module.exports = ghostBookshelf;
|