mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-10 23:36:14 -05:00
no issue - the `Bookshelf` type wasn't being imported anywhere and editors were showing warnings for the missing type - also fixes use of `Bookshelf.Model` - this doesn't work if we declare `Bookshelf` using a `@typedef` and the preferred syntax is using an array index - note: it still complains because we're calling functions that are only declared in our custom Bookshelf Model but this is a step in the right direction
80 lines
2.3 KiB
JavaScript
80 lines
2.3 KiB
JavaScript
const _ = require('lodash');
|
|
const _debug = require('ghost-ignition').debug._base;
|
|
const debug = _debug('ghost-query');
|
|
|
|
/**
|
|
* Enchances knex query builder with a join to relation configured in
|
|
*
|
|
* @param {Bookshelf.Model} model instance of Bookshelf model
|
|
* @param {String[]} relationsToLoad relations to be included in joins
|
|
*/
|
|
function withEager(model, relationsToLoad) {
|
|
const tableName = _.result(model.constructor.prototype, 'tableName');
|
|
|
|
return function (qb) {
|
|
if (!model.relationsMeta) {
|
|
return qb;
|
|
}
|
|
|
|
for (const [key, config] of Object.entries(model.relationsMeta)) {
|
|
if (relationsToLoad.includes(key)) {
|
|
const innerQb = qb
|
|
.leftJoin(config.targetTableName, `${tableName}.id`, `${config.targetTableName}.${config.foreignKey}`);
|
|
|
|
debug(`QUERY has posts: ${innerQb.toSQL().sql}`);
|
|
}
|
|
}
|
|
|
|
return qb;
|
|
};
|
|
}
|
|
|
|
function load(options) {
|
|
if (!options) {
|
|
return;
|
|
}
|
|
|
|
if (this.eagerLoad) {
|
|
if (!options.columns && options.withRelated && _.intersection(this.eagerLoad, options.withRelated).length) {
|
|
this.query(withEager(this, this.eagerLoad));
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* ## Pagination
|
|
* Extends `bookshelf.Model` native `fetch` and `fetchAll` methods with
|
|
* a join to "eager loaded" relation. An exaple of such loading is when
|
|
* there is a need to order by fields in the related table.
|
|
*
|
|
* @param {import('bookshelf')} Bookshelf
|
|
*/
|
|
module.exports = function eagerLoadPlugin(Bookshelf) {
|
|
const modelPrototype = Bookshelf.Model.prototype;
|
|
|
|
Bookshelf.Model = Bookshelf.Model.extend({
|
|
initialize: function () {
|
|
return modelPrototype.initialize.apply(this, arguments);
|
|
},
|
|
|
|
fetch: function () {
|
|
load.apply(this, arguments);
|
|
|
|
if (_debug.enabled('ghost-query')) {
|
|
debug('QUERY', this.query().toQuery());
|
|
}
|
|
|
|
return modelPrototype.fetch.apply(this, arguments);
|
|
},
|
|
|
|
fetchAll: function () {
|
|
load.apply(this, arguments);
|
|
|
|
if (_debug.enabled('ghost-query')) {
|
|
debug('QUERY', this.query().toQuery());
|
|
}
|
|
|
|
return modelPrototype.fetchAll.apply(this, arguments);
|
|
}
|
|
});
|
|
};
|