mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-22 18:31:57 +03:00
bbcc83dadb
refs #11729 - When ordering is done by fields from a relation (like post's `meta_title` that comes form `posts_meta` table), Bookshelf does not include those relations in the original query which caused errors. To support this usecase added a mechanism to detect fields from a relation and load those relations into query. - Extended ordering to include table name in ordered field name. The information about the table name is needed to avoid using `tableName` within pagination plugin and gives path to having other than original table ordering fields (e.g. order by posts_meta table fields) - Added test case to check ordering on posts_meta fields - Added support for "eager loading" relations. Allows to extend query builder object with joins to related tables, which could be used in ordering (possibly in filtering later). Bookshelf does not support ordering/filtering by proprieties coming from relations, that's why this kind of plugin and query expansion is needed - Added note about lack of support for child relations with same property names.
55 lines
1.8 KiB
JavaScript
55 lines
1.8 KiB
JavaScript
const _ = require('lodash');
|
|
|
|
const order = function order(Bookshelf) {
|
|
Bookshelf.Model = Bookshelf.Model.extend({
|
|
orderAttributes() {},
|
|
|
|
parseOrderOption: function (orderQueryString, withRelated) {
|
|
let orderAttributes;
|
|
let result;
|
|
let rules;
|
|
|
|
orderAttributes = this.orderAttributes();
|
|
if (withRelated && withRelated.indexOf('count.posts') > -1) {
|
|
orderAttributes.push('count.posts');
|
|
}
|
|
result = {};
|
|
rules = orderQueryString.split(',');
|
|
|
|
_.each(rules, function (rule) {
|
|
let match;
|
|
let field;
|
|
let direction;
|
|
|
|
match = /^([a-z0-9_.]+)\s+(asc|desc)$/i.exec(rule.trim());
|
|
|
|
// invalid order syntax
|
|
if (!match) {
|
|
return;
|
|
}
|
|
|
|
field = match[1].toLowerCase();
|
|
direction = match[2].toUpperCase();
|
|
|
|
const matchingOrderAttribute = orderAttributes.find((orderAttribute) => {
|
|
// NOTE: this logic assumes we use different field names for "parent" and "child" relations.
|
|
// E.g.: ['parent.title', 'child.title'] and ['child.title', 'parent.title'] - would not
|
|
// distinguish on which relation to sort neither which order to pick the fields on.
|
|
// For more context see: https://github.com/TryGhost/Ghost/pull/12226#discussion_r493085098
|
|
return orderAttribute.endsWith(field);
|
|
});
|
|
|
|
if (!matchingOrderAttribute) {
|
|
return;
|
|
}
|
|
|
|
result[matchingOrderAttribute] = direction;
|
|
});
|
|
|
|
return result;
|
|
}
|
|
});
|
|
};
|
|
|
|
module.exports = order;
|