mirror of
https://github.com/strapi/strapi.git
synced 2025-12-27 07:03:38 +00:00
Enhance polymorphic syntax
This commit is contained in:
parent
26c10cddd0
commit
946f0f17b3
@ -160,17 +160,17 @@ module.exports = function(strapi) {
|
||||
|
||||
// Reformat data by bypassing the many-to-many relationship.
|
||||
switch (association.nature) {
|
||||
case 'oneToMorph':
|
||||
case 'oneToManyMorph':
|
||||
attrs[association.alias] = attrs[association.alias][model.collectionName];
|
||||
break;
|
||||
case 'manyToMorph':
|
||||
case 'manyToManyMorph':
|
||||
attrs[association.alias] = attrs[association.alias].map(rel => rel[model.collectionName]);
|
||||
break;
|
||||
case 'morphToOne':
|
||||
attrs[association.alias] = attrs[association.alias][association.alias];
|
||||
case 'oneMorphToOne':
|
||||
attrs[association.alias] = attrs[association.alias].related;
|
||||
break;
|
||||
case 'morphToMany':
|
||||
attrs[association.alias] = attrs[association.alias].map(rel => rel[association.alias]);
|
||||
case 'manyMorphToOne':
|
||||
attrs[association.alias] = attrs[association.alias].map(obj => obj.related);
|
||||
break;
|
||||
default:
|
||||
|
||||
@ -313,9 +313,15 @@ module.exports = function(strapi) {
|
||||
name
|
||||
);
|
||||
|
||||
const globalId = details.plugin ?
|
||||
_.get(strapi.plugins,`${details.plugin}.models.${(details.model || details.collection || '').toLowerCase()}.globalId`):
|
||||
_.get(strapi.models, `${(details.model || details.collection || '').toLowerCase()}.globalId`);
|
||||
let globalId;
|
||||
const globalName = details.model || details.collection || '';
|
||||
|
||||
// Exclude polymorphic association.
|
||||
if (globalName !== '*') {
|
||||
globalId = details.plugin ?
|
||||
_.get(strapi.plugins,`${details.plugin}.models.${globalName.toLowerCase()}.globalId`):
|
||||
_.get(strapi.models, `${globalName.toLowerCase()}.globalId`);
|
||||
}
|
||||
|
||||
switch (verbose) {
|
||||
case 'hasOne': {
|
||||
|
||||
@ -106,11 +106,11 @@ module.exports = function (strapi) {
|
||||
if (this._mongooseOptions.populate && this._mongooseOptions.populate[association.alias]) {
|
||||
if (association.nature === 'oneToMorph' || association.nature === 'manyToMorph') {
|
||||
this._mongooseOptions.populate[association.alias].match = {
|
||||
[`${association.via}.${association.where}`]: association.alias,
|
||||
[`${association.via}.${association.filter}`]: association.alias,
|
||||
[`${association.via}.kind`]: definition.globalId
|
||||
}
|
||||
} else {
|
||||
this._mongooseOptions.populate[association.alias].path = `${association.alias}.${association.key}`;
|
||||
this._mongooseOptions.populate[association.alias].path = `${association.alias}.${association.filter}`;
|
||||
}
|
||||
}
|
||||
|
||||
@ -163,7 +163,7 @@ module.exports = function (strapi) {
|
||||
transform: function (doc, returned, opts) {
|
||||
morphAssociations.forEach(association => {
|
||||
if (Array.isArray(returned[association.alias]) && returned[association.alias].length > 0) {
|
||||
returned[association.alias] = returned[association.alias].map(o => o[association.key]);
|
||||
returned[association.alias] = returned[association.alias].map(o => o[association.filter]);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -332,14 +332,11 @@ module.exports = function (strapi) {
|
||||
case 'morphOne': {
|
||||
const FK = _.find(definition.associations, {alias: name});
|
||||
const ref = details.plugin ? strapi.plugins[details.plugin].models[details.model].globalId : strapi.models[details.model].globalId;
|
||||
const key = details.plugin ?
|
||||
strapi.plugins[details.plugin].models[details.model].attributes[details.via].key:
|
||||
strapi.models[details.model].attributes[details.via].key;
|
||||
|
||||
definition.loadedModel[name] = {
|
||||
type: 'virtual',
|
||||
ref,
|
||||
via: `${FK.via}.${key}`,
|
||||
via: `${FK.via}.ref`,
|
||||
justOne: true
|
||||
};
|
||||
|
||||
@ -350,14 +347,11 @@ module.exports = function (strapi) {
|
||||
case 'morphMany': {
|
||||
const FK = _.find(definition.associations, {alias: name});
|
||||
const ref = details.plugin ? strapi.plugins[details.plugin].models[details.collection].globalId : strapi.models[details.collection].globalId;
|
||||
const key = details.plugin ?
|
||||
strapi.plugins[details.plugin].models[details.collection].attributes[details.via].key:
|
||||
strapi.models[details.collection].attributes[details.via].key;
|
||||
|
||||
definition.loadedModel[name] = {
|
||||
type: 'virtual',
|
||||
ref,
|
||||
via: `${FK.via}.${key}`
|
||||
via: `${FK.via}.ref`
|
||||
};
|
||||
|
||||
// Set this info to be able to see if this field is a real database's field.
|
||||
@ -367,8 +361,8 @@ module.exports = function (strapi) {
|
||||
case 'belongsToMorph': {
|
||||
definition.loadedModel[name] = {
|
||||
kind: String,
|
||||
[details.where]: String,
|
||||
[details.key]: {
|
||||
[details.filter]: String,
|
||||
ref: {
|
||||
type: instance.Schema.Types.ObjectId,
|
||||
refPath: `${name}.kind`
|
||||
}
|
||||
@ -378,8 +372,8 @@ module.exports = function (strapi) {
|
||||
case 'belongsToManyMorph': {
|
||||
definition.loadedModel[name] = [{
|
||||
kind: String,
|
||||
[details.where]: String,
|
||||
[details.key]: {
|
||||
[details.filter]: String,
|
||||
ref: {
|
||||
type: instance.Schema.Types.ObjectId,
|
||||
refPath: `${name}.kind`
|
||||
}
|
||||
|
||||
@ -41,11 +41,11 @@
|
||||
},
|
||||
"avatar": {
|
||||
"model": "upload",
|
||||
"via": "related"
|
||||
"via": "uploaded"
|
||||
},
|
||||
"photos": {
|
||||
"collection": "upload",
|
||||
"via": "related"
|
||||
"via": "uploaded"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -83,18 +83,53 @@ module.exports = {
|
||||
models = association.plugin ? strapi.plugins[association.plugin].models : strapi.models;
|
||||
}
|
||||
|
||||
if (association.hasOwnProperty('via') && association.hasOwnProperty('collection')) {
|
||||
if ((association.hasOwnProperty('collection') && association.collection === '*') || (association.hasOwnProperty('model') && association.model === '*')) {
|
||||
if (association.model) {
|
||||
types.current = 'morphToD';
|
||||
} else {
|
||||
types.current = 'morphTo';
|
||||
}
|
||||
|
||||
const flattenedPluginsModels = Object.keys(strapi.plugins).reduce((acc, current) => {
|
||||
Object.keys(strapi.plugins[current].models).forEach((model) => {
|
||||
acc[`${current}_${model}`] = strapi.plugins[current].models[model];
|
||||
});
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
const allModels = _.merge({}, strapi.models, flattenedPluginsModels);
|
||||
|
||||
// We have to find if they are a model linked to this key
|
||||
_.forIn(allModels, model => {
|
||||
_.forIn(model.attributes, attribute => {
|
||||
if (attribute.hasOwnProperty('via') && attribute.via === key) {
|
||||
if (attribute.hasOwnProperty('collection')) {
|
||||
types.other = 'collection';
|
||||
|
||||
// Break loop
|
||||
return false;
|
||||
} else if (attribute.hasOwnProperty('model')) {
|
||||
types.other = 'model';
|
||||
|
||||
// Break loop
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
} else if (association.hasOwnProperty('via') && association.hasOwnProperty('collection')) {
|
||||
const relatedAttribute = models[association.collection].attributes[association.via];
|
||||
|
||||
types.current = 'collection';
|
||||
|
||||
if (relatedAttribute.hasOwnProperty('collection') && relatedAttribute.hasOwnProperty('via')) {
|
||||
if (relatedAttribute.hasOwnProperty('collection') && relatedAttribute.collection !== '*' && relatedAttribute.hasOwnProperty('via')) {
|
||||
types.other = 'collection';
|
||||
} else if (relatedAttribute.hasOwnProperty('collection') && !relatedAttribute.hasOwnProperty('via')) {
|
||||
} else if (relatedAttribute.hasOwnProperty('collection') && relatedAttribute.collection !== '*' && !relatedAttribute.hasOwnProperty('via')) {
|
||||
types.other = 'collectionD';
|
||||
} else if (relatedAttribute.hasOwnProperty('model')) {
|
||||
} else if (relatedAttribute.hasOwnProperty('model') && relatedAttribute.model !== '*') {
|
||||
types.other = 'model';
|
||||
} else if (relatedAttribute.hasOwnProperty('key')) {
|
||||
} else if (relatedAttribute.hasOwnProperty('collection') || relatedAttribute.hasOwnProperty('model')) {
|
||||
types.other = 'morphTo';
|
||||
}
|
||||
} else if (association.hasOwnProperty('via') && association.hasOwnProperty('model')) {
|
||||
@ -103,17 +138,17 @@ module.exports = {
|
||||
// We have to find if they are a model linked to this key
|
||||
_.forIn(_.omit(models, currentModelName || ''), model => {
|
||||
_.forIn(model.attributes, attribute => {
|
||||
if (attribute.hasOwnProperty('via') && attribute.via === key && attribute.hasOwnProperty('collection')) {
|
||||
if (attribute.hasOwnProperty('via') && attribute.via === key && attribute.hasOwnProperty('collection') && attribute.collection !== '*') {
|
||||
types.other = 'collection';
|
||||
|
||||
// Break loop
|
||||
return false;
|
||||
} else if (attribute.hasOwnProperty('model')) {
|
||||
} else if (attribute.hasOwnProperty('model') && attribute.model !== '*') {
|
||||
types.other = 'model';
|
||||
|
||||
// Break loop
|
||||
return false;
|
||||
} else if (attribute.hasOwnProperty('key')) {
|
||||
} else if (attribute.hasOwnProperty('collection') || attribute.hasOwnProperty('model')) {
|
||||
types.other = 'morphTo';
|
||||
|
||||
// Break loop
|
||||
@ -157,41 +192,6 @@ module.exports = {
|
||||
} else if (attribute.hasOwnProperty('model')) {
|
||||
types.other = 'modelD';
|
||||
|
||||
// Break loop
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
} else if (association.hasOwnProperty('morphTo')) {
|
||||
if (association.morphTo === 'single') {
|
||||
types.current = 'morphToD';
|
||||
} else {
|
||||
types.current = 'morphTo';
|
||||
}
|
||||
|
||||
const flattenedPluginsModels = Object.keys(strapi.plugins).reduce((acc, current) => {
|
||||
Object.keys(strapi.plugins[current].models).forEach((model) => {
|
||||
acc[`${current}_${model}`] = strapi.plugins[current].models[model];
|
||||
});
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
const allModels = _.merge({}, strapi.models, flattenedPluginsModels);
|
||||
|
||||
// We have to find if they are a model linked to this key
|
||||
_.forIn(allModels, model => {
|
||||
_.forIn(model.attributes, attribute => {
|
||||
if (attribute.hasOwnProperty('via') && attribute.via === key) {
|
||||
if (attribute.hasOwnProperty('collection')) {
|
||||
types.other = 'collection';
|
||||
|
||||
// Break loop
|
||||
return false;
|
||||
} else if (attribute.hasOwnProperty('model')) {
|
||||
types.other = 'model';
|
||||
|
||||
// Break loop
|
||||
return false;
|
||||
}
|
||||
@ -207,7 +207,7 @@ module.exports = {
|
||||
};
|
||||
} else if (types.current === 'collection' && types.other === 'morphToD') {
|
||||
return {
|
||||
nature: 'manyToMorph',
|
||||
nature: 'manyToOneMorph',
|
||||
verbose: 'morphMany'
|
||||
};
|
||||
} else if (types.current === 'modelD' && types.other === 'morphTo') {
|
||||
@ -217,17 +217,17 @@ module.exports = {
|
||||
};
|
||||
} else if (types.current === 'modelD' && types.other === 'morphToD') {
|
||||
return {
|
||||
nature: 'oneToMorph',
|
||||
nature: 'oneToOneMorph',
|
||||
verbose: 'morphOne'
|
||||
};
|
||||
} else if (types.current === 'morphToD' && types.other === 'collection') {
|
||||
return {
|
||||
nature: 'morphToMany',
|
||||
nature: 'oneMorphToMany',
|
||||
verbose: 'belongsToMorph'
|
||||
};
|
||||
} else if (types.current === 'morphToD' && types.other === 'model') {
|
||||
return {
|
||||
nature: 'morphToOne',
|
||||
nature: 'oneMorphToOne',
|
||||
verbose: 'belongsToMorph'
|
||||
};
|
||||
} else if (types.current === 'morphTo' && types.other === 'model') {
|
||||
@ -315,16 +315,21 @@ module.exports = {
|
||||
}
|
||||
|
||||
// Exclude non-relational attribute
|
||||
if (!association.hasOwnProperty('collection') && !association.hasOwnProperty('model') && !association.hasOwnProperty('morphTo')) {
|
||||
if (!association.hasOwnProperty('collection') && !association.hasOwnProperty('model')) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Get relation nature
|
||||
let details;
|
||||
const globalName = association.model || association.collection || '';
|
||||
const infos = this.getNature(association, key, undefined, model.toLowerCase());
|
||||
const details = _.get(strapi.models, `${association.model || association.collection}.attributes.${association.via}`, {});
|
||||
|
||||
if (globalName !== '*') {
|
||||
details = _.get(strapi.models, `${globalName}.attributes.${association.via}`, {});
|
||||
}
|
||||
|
||||
// Build associations object
|
||||
if (association.hasOwnProperty('collection')) {
|
||||
if (association.hasOwnProperty('collection') && association.collection !== '*') {
|
||||
definition.associations.push({
|
||||
alias: key,
|
||||
type: 'collection',
|
||||
@ -336,7 +341,7 @@ module.exports = {
|
||||
plugin: association.plugin || undefined,
|
||||
where: details.where,
|
||||
});
|
||||
} else if (association.hasOwnProperty('model')) {
|
||||
} else if (association.hasOwnProperty('model') && association.model !== '*') {
|
||||
definition.associations.push({
|
||||
alias: key,
|
||||
type: 'model',
|
||||
@ -348,7 +353,7 @@ module.exports = {
|
||||
plugin: association.plugin || undefined,
|
||||
where: details.where,
|
||||
});
|
||||
} else if (association.hasOwnProperty('morphTo')) {
|
||||
} else if (association.hasOwnProperty('collection') || association.hasOwnProperty('model')) {
|
||||
const pluginsModels = Object.keys(strapi.plugins).reduce((acc, current) => {
|
||||
Object.keys(strapi.plugins[current].models).forEach((entity) => {
|
||||
Object.keys(strapi.plugins[current].models[entity].attributes).forEach((attribute) => {
|
||||
@ -384,11 +389,11 @@ module.exports = {
|
||||
|
||||
definition.associations.push({
|
||||
alias: key,
|
||||
type: association.morphTo === 'single' ? 'model' : 'collection',
|
||||
type: association.model ? 'model' : 'collection',
|
||||
related: models,
|
||||
nature: infos.nature,
|
||||
autoPopulate: _.get(association, 'autoPopulate', true),
|
||||
key: association.key,
|
||||
filter: association.filter,
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user