mirror of
https://github.com/strapi/strapi.git
synced 2025-08-19 14:19:03 +00:00
Make GraphQL polymorphic relationships working with Bookshelf
This commit is contained in:
parent
c59ad9d958
commit
17c46b331d
@ -176,6 +176,7 @@ module.exports = function(strapi) {
|
|||||||
attrs[association.alias] = attrs[association.alias].related;
|
attrs[association.alias] = attrs[association.alias].related;
|
||||||
break;
|
break;
|
||||||
case 'manyMorphToOne':
|
case 'manyMorphToOne':
|
||||||
|
case 'manyMorphToMany':
|
||||||
attrs[association.alias] = attrs[association.alias].map(obj => obj.related);
|
attrs[association.alias] = attrs[association.alias].map(obj => obj.related);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -226,7 +227,6 @@ module.exports = function(strapi) {
|
|||||||
const association = definition.associations
|
const association = definition.associations
|
||||||
.filter(association => association.nature.toLowerCase().indexOf('morph') !== -1)
|
.filter(association => association.nature.toLowerCase().indexOf('morph') !== -1)
|
||||||
.filter(association => association.alias === path || association.via === path)[0];
|
.filter(association => association.alias === path || association.via === path)[0];
|
||||||
|
|
||||||
if (association) {
|
if (association) {
|
||||||
// Override on polymorphic path only.
|
// Override on polymorphic path only.
|
||||||
if (_.isString(path) && path === association.via) {
|
if (_.isString(path) && path === association.via) {
|
||||||
|
@ -29,16 +29,37 @@ module.exports = {
|
|||||||
.count();
|
.count();
|
||||||
},
|
},
|
||||||
|
|
||||||
findOne: async function (params) {
|
findOne: async function (params, populate, raw = true) {
|
||||||
const record = await this
|
const record = await this
|
||||||
.forge({
|
.forge({
|
||||||
[this.primaryKey]: params[this.primaryKey]
|
[this.primaryKey]: params[this.primaryKey]
|
||||||
})
|
})
|
||||||
.fetch({
|
.fetch({
|
||||||
withRelated: this.associations.map(x => x.alias)
|
withRelated: populate || this.associations.map(x => x.alias)
|
||||||
});
|
});
|
||||||
|
|
||||||
return record ? record.toJSON() : record;
|
const data = record ? record.toJSON() : record;
|
||||||
|
|
||||||
|
// Retrieve data manually.
|
||||||
|
if (_.isEmpty(populate)) {
|
||||||
|
const arrayOfPromises = this.associations
|
||||||
|
.filter(association => ['manyMorphToOne', 'manyMorphToMany'].includes(association.nature))
|
||||||
|
.map(association => {
|
||||||
|
return this.morph.forge()
|
||||||
|
.where({
|
||||||
|
[`${this.collectionName}_id`]: params[this.primaryKey]
|
||||||
|
})
|
||||||
|
.fetchAll()
|
||||||
|
});
|
||||||
|
|
||||||
|
const related = await Promise.all(arrayOfPromises);
|
||||||
|
|
||||||
|
related.forEach((value, index) => {
|
||||||
|
data[this.associations[index].alias] = value ? value.toJSON() : value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
},
|
},
|
||||||
|
|
||||||
create: async function (params) {
|
create: async function (params) {
|
||||||
|
@ -475,31 +475,38 @@ module.exports = {
|
|||||||
acc.resolver[globalId] = {};
|
acc.resolver[globalId] = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (association.nature === 'manyMorphToMany') {
|
switch (association.nature) {
|
||||||
return _.merge(acc.resolver[globalId], {
|
case 'manyMorphToOne':
|
||||||
[association.alias]: async (obj, options, context) => {
|
case 'manyMorphToMany':
|
||||||
const [ withRelated, withoutRelated ] = await Promise.all([
|
return _.merge(acc.resolver[globalId], {
|
||||||
resolvers.fetch({
|
[association.alias]: async (obj, options, context) => {
|
||||||
id: obj[model.primaryKey],
|
const [ withRelated, withoutRelated ] = await Promise.all([
|
||||||
model: name
|
resolvers.fetch({
|
||||||
}, plugin, [association.alias], false),
|
id: obj[model.primaryKey],
|
||||||
resolvers.fetch({
|
model: name
|
||||||
id: obj[model.primaryKey],
|
}, plugin, [association.alias], false),
|
||||||
model: name
|
resolvers.fetch({
|
||||||
}, plugin, [])
|
id: obj[model.primaryKey],
|
||||||
]);
|
model: name
|
||||||
|
}, plugin, [])
|
||||||
|
]);
|
||||||
|
|
||||||
const entry = withRelated.toJSON ? withRelated.toJSON() : withRelated;
|
const entry = withRelated.toJSON ? withRelated.toJSON() : withRelated;
|
||||||
|
|
||||||
entry[association.alias].map((entry, index) => {
|
entry[association.alias].map((entry, index) => {
|
||||||
entry._type = withoutRelated[association.alias][index].kind;
|
const type = withoutRelated[association.alias][index].kind ||
|
||||||
|
_.upperFirst(_.camelCase(withoutRelated[association.alias][index][`${association.alias}_type`]));
|
||||||
|
|
||||||
return entry;
|
entry._type = type;
|
||||||
});
|
|
||||||
|
|
||||||
return entry[association.alias];
|
return entry;
|
||||||
}
|
});
|
||||||
});
|
|
||||||
|
return entry[association.alias];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
@ -520,13 +527,13 @@ module.exports = {
|
|||||||
} else {
|
} else {
|
||||||
// Get attribute.
|
// Get attribute.
|
||||||
const attr = association.plugin ?
|
const attr = association.plugin ?
|
||||||
strapi.plugins[association.plugin].models[association.collection].attributes[association.via]:
|
strapi.plugins[association.plugin].models[params.model].attributes[association.via]:
|
||||||
strapi.models[association.collection].attributes[association.via];
|
strapi.models[params.model].attributes[association.via];
|
||||||
|
|
||||||
// Get refering model.
|
// Get refering model.
|
||||||
const ref = attr.plugin ?
|
const ref = attr.plugin ?
|
||||||
strapi.plugins[attr.plugin].models[attr.model || attr.collection]:
|
strapi.plugins[attr.plugin].models[params.model]:
|
||||||
strapi.models[attr.model || attr.collection];
|
strapi.models[params.model];
|
||||||
|
|
||||||
// Apply optional arguments to make more precise nested request.
|
// Apply optional arguments to make more precise nested request.
|
||||||
const convertedParams = strapi.utils.models.convertParams(name, this.convertToParams(options));
|
const convertedParams = strapi.utils.models.convertParams(name, this.convertToParams(options));
|
||||||
@ -668,7 +675,7 @@ module.exports = {
|
|||||||
polymorphicDef: `union Morph = ${types.join(' | ')}`,
|
polymorphicDef: `union Morph = ${types.join(' | ')}`,
|
||||||
polymorphicResolver: {
|
polymorphicResolver: {
|
||||||
Morph: {
|
Morph: {
|
||||||
__resolveType(obj, context, info){
|
__resolveType(obj, context, info) {
|
||||||
return obj.kind || obj._type;
|
return obj.kind || obj._type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
module.exports = {
|
||||||
|
type: {
|
||||||
|
UsersPermissionsPermission: false // Make this type NOT queriable.
|
||||||
|
},
|
||||||
|
resolver: {
|
||||||
|
Query: {
|
||||||
|
role: {
|
||||||
|
resolverOf: 'UsersPermissions.getRole',
|
||||||
|
resolver: async (obj, options, ctx) => {
|
||||||
|
await strapi.plugins['users-permissions'].controllers.userspermissions.getRole(ctx);
|
||||||
|
|
||||||
|
return ctx.body.role;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
roles: {
|
||||||
|
resolverOf: 'UsersPermissions.getRoles', // Apply the `getRoles` permissions on the resolver.
|
||||||
|
resolver: async (obj, options, ctx) => {
|
||||||
|
await strapi.plugins['users-permissions'].controllers.userspermissions.getRoles(ctx);
|
||||||
|
|
||||||
|
return ctx.body.roles;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user