mirror of
https://github.com/strapi/strapi.git
synced 2025-10-12 08:36:40 +00:00
Update algorithm to correctly add, edit and delete relationships between models and plugins' models
This commit is contained in:
parent
1f55ca1d04
commit
6ac1bca417
@ -33,7 +33,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
createModel: async ctx => {
|
createModel: async ctx => {
|
||||||
const { name, description, connection, collectionName, attributes = [] } = ctx.request.body;
|
const { name, description, connection, collectionName, attributes = [], plugin } = ctx.request.body;
|
||||||
|
|
||||||
if (!name) return ctx.badRequest(null, [{ messages: [{ id: 'request.error.name.missing' }] }]);
|
if (!name) return ctx.badRequest(null, [{ messages: [{ id: 'request.error.name.missing' }] }]);
|
||||||
if (!_.includes(Service.getConnections(), connection)) return ctx.badRequest(null, [{ messages: [{ id: 'request.error.connection.unknow' }] }]);
|
if (!_.includes(Service.getConnections(), connection)) return ctx.badRequest(null, [{ messages: [{ id: 'request.error.connection.unknow' }] }]);
|
||||||
@ -50,20 +50,20 @@ module.exports = {
|
|||||||
|
|
||||||
await Service.generateAPI(name, description, connection, collectionName, []);
|
await Service.generateAPI(name, description, connection, collectionName, []);
|
||||||
|
|
||||||
const modelFilePath = Service.getModelPath(name);
|
const modelFilePath = Service.getModelPath(name, plugin);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const modelJSON = require(modelFilePath);
|
const modelJSON = _.cloneDeep(require(modelFilePath));
|
||||||
|
|
||||||
modelJSON.attributes = formatedAttributes;
|
modelJSON.attributes = formatedAttributes;
|
||||||
|
|
||||||
const clearRelationsErrors = Service.clearRelations(name);
|
const clearRelationsErrors = Service.clearRelations(name, plugin);
|
||||||
|
|
||||||
if (!_.isEmpty(clearRelationsErrors)) {
|
if (!_.isEmpty(clearRelationsErrors)) {
|
||||||
return ctx.badRequest(null, [{ messages: clearRelationsErrors }]);
|
return ctx.badRequest(null, [{ messages: clearRelationsErrors }]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const createRelationsErrors = Service.createRelations(name, attributes);
|
const createRelationsErrors = Service.createRelations(name, attributes, plugin);
|
||||||
|
|
||||||
if (!_.isEmpty(createRelationsErrors)) {
|
if (!_.isEmpty(createRelationsErrors)) {
|
||||||
return ctx.badRequest(null, [{ messages: createRelationsErrors }]);
|
return ctx.badRequest(null, [{ messages: createRelationsErrors }]);
|
||||||
@ -92,6 +92,8 @@ module.exports = {
|
|||||||
if (strapi.models[_.toLower(name)] && name !== model) return ctx.badRequest(null, [{ messages: [{ id: 'request.error.model.exist' }] }]);
|
if (strapi.models[_.toLower(name)] && name !== model) return ctx.badRequest(null, [{ messages: [{ id: 'request.error.model.exist' }] }]);
|
||||||
if (!strapi.models[_.toLower(model)]) return ctx.badRequest(null, [{ messages: [{ id: 'request.error.model.unknow' }] }]);
|
if (!strapi.models[_.toLower(model)]) return ctx.badRequest(null, [{ messages: [{ id: 'request.error.model.unknow' }] }]);
|
||||||
if (!_.isNaN(parseFloat(name[0]))) return ctx.badRequest(null, [{ messages: [{ id: 'request.error.model.name' }] }]);
|
if (!_.isNaN(parseFloat(name[0]))) return ctx.badRequest(null, [{ messages: [{ id: 'request.error.model.name' }] }]);
|
||||||
|
if (plugin && !strapi.plugins[_.toLower(plugin)]) return ctx.badRequest(null, [{ message: [{ id: 'request.error.plugin.name' }] }]);
|
||||||
|
if (plugin && !strapi.plugins[_.toLower(plugin)].models[_.toLower(model)]) return ctx.badRequest(null, [{ message: [{ id: 'request.error.model.unknow' }] }]);
|
||||||
|
|
||||||
const [formatedAttributes, attributesErrors] = Service.formatAttributes(attributes);
|
const [formatedAttributes, attributesErrors] = Service.formatAttributes(attributes);
|
||||||
|
|
||||||
@ -108,7 +110,7 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const modelJSON = require(modelFilePath);
|
const modelJSON = _.cloneDeep(require(modelFilePath));
|
||||||
|
|
||||||
modelJSON.attributes = formatedAttributes;
|
modelJSON.attributes = formatedAttributes;
|
||||||
modelJSON.info = {
|
modelJSON.info = {
|
||||||
@ -118,13 +120,13 @@ module.exports = {
|
|||||||
modelJSON.connection = connection;
|
modelJSON.connection = connection;
|
||||||
modelJSON.collectionName = collectionName;
|
modelJSON.collectionName = collectionName;
|
||||||
|
|
||||||
const clearRelationsErrors = Service.clearRelations(model);
|
const clearRelationsErrors = Service.clearRelations(model, plugin);
|
||||||
|
|
||||||
if (!_.isEmpty(clearRelationsErrors)) {
|
if (!_.isEmpty(clearRelationsErrors)) {
|
||||||
return ctx.badRequest(null, [{ messages: clearRelationsErrors }]);
|
return ctx.badRequest(null, [{ messages: clearRelationsErrors }]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const createRelationsErrors = Service.createRelations(name, attributes);
|
const createRelationsErrors = Service.createRelations(name, attributes, plugin);
|
||||||
|
|
||||||
if (!_.isEmpty(createRelationsErrors)) {
|
if (!_.isEmpty(createRelationsErrors)) {
|
||||||
return ctx.badRequest(null, [{ messages: createRelationsErrors }]);
|
return ctx.badRequest(null, [{ messages: createRelationsErrors }]);
|
||||||
|
@ -74,8 +74,6 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
generateAPI: (name, description, connection, collectionName, attributes) => {
|
generateAPI: (name, description, connection, collectionName, attributes) => {
|
||||||
description = _.replace(description, /\"/g, '\\"');
|
|
||||||
|
|
||||||
const template = _.get(strapi.config.currentEnvironment, `database.connections.${connection}.connector`, 'strapi-mongoose').split('-')[1];
|
const template = _.get(strapi.config.currentEnvironment, `database.connections.${connection}.connector`, 'strapi-mongoose').split('-')[1];
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@ -85,7 +83,7 @@ module.exports = {
|
|||||||
rootPath: strapi.config.appPath,
|
rootPath: strapi.config.appPath,
|
||||||
args: {
|
args: {
|
||||||
api: name,
|
api: name,
|
||||||
description,
|
description: _.replace(description, /\"/g, '\\"'),
|
||||||
attributes,
|
attributes,
|
||||||
connection,
|
connection,
|
||||||
collectionName: !_.isEmpty(collectionName) ? collectionName : undefined,
|
collectionName: !_.isEmpty(collectionName) ? collectionName : undefined,
|
||||||
@ -97,8 +95,8 @@ module.exports = {
|
|||||||
success: () => {
|
success: () => {
|
||||||
resolve();
|
resolve();
|
||||||
},
|
},
|
||||||
error: () => {
|
error: (err) => {
|
||||||
reject();
|
reject(err);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -106,8 +104,9 @@ module.exports = {
|
|||||||
|
|
||||||
getModelPath: (model, plugin) => {
|
getModelPath: (model, plugin) => {
|
||||||
// Retrieve where is located the model.
|
// Retrieve where is located the model.
|
||||||
|
// Note: The target is not found when we are creating a new API. That's why, we are returning the lowercased model.
|
||||||
const target = Object.keys((plugin ? strapi.plugins : strapi.api) || {})
|
const target = Object.keys((plugin ? strapi.plugins : strapi.api) || {})
|
||||||
.filter(x => _.includes(Object.keys((plugin ? strapi.plugins : strapi.api)[x].models), model.toLowerCase()))[0];
|
.filter(x => _.includes(Object.keys((plugin ? strapi.plugins : strapi.api)[x].models), model.toLowerCase()))[0] || model.toLowerCase();
|
||||||
|
|
||||||
// Retrieve the filename of the model.
|
// Retrieve the filename of the model.
|
||||||
const filename = fs.readdirSync(plugin ? path.join(strapi.config.appPath, 'plugins', target, 'models') : path.join(strapi.config.appPath, 'api', target, 'models'))
|
const filename = fs.readdirSync(plugin ? path.join(strapi.config.appPath, 'plugins', target, 'models') : path.join(strapi.config.appPath, 'api', target, 'models'))
|
||||||
@ -148,6 +147,7 @@ module.exports = {
|
|||||||
|
|
||||||
attr.via = relation.key;
|
attr.via = relation.key;
|
||||||
attr.dominant = relation.dominant;
|
attr.dominant = relation.dominant;
|
||||||
|
attr.plugin = relation.pluginValue;
|
||||||
|
|
||||||
attrs[attribute.name] = attr;
|
attrs[attribute.name] = attr;
|
||||||
}
|
}
|
||||||
@ -165,7 +165,7 @@ module.exports = {
|
|||||||
return [attrs, errors];
|
return [attrs, errors];
|
||||||
},
|
},
|
||||||
|
|
||||||
clearRelations: model => {
|
clearRelations: (model, source) => {
|
||||||
const errors = [];
|
const errors = [];
|
||||||
const structure = {
|
const structure = {
|
||||||
models: strapi.models,
|
models: strapi.models,
|
||||||
@ -181,7 +181,13 @@ module.exports = {
|
|||||||
// Method to delete the association of the models.
|
// Method to delete the association of the models.
|
||||||
const deleteAssociations = (models, plugin) => {
|
const deleteAssociations = (models, plugin) => {
|
||||||
Object.keys(models).forEach(name => {
|
Object.keys(models).forEach(name => {
|
||||||
const relationsToDelete = _.get(plugin ? strapi.plugins[plugin].models[name] : strapi.models[name], 'associations', []).filter(association => association[association.type] === model);
|
const relationsToDelete = _.get(plugin ? strapi.plugins[plugin].models[name] : strapi.models[name], 'associations', []).filter(association => {
|
||||||
|
if (source) {
|
||||||
|
return association[association.type] === model && association.plugin === source;
|
||||||
|
}
|
||||||
|
|
||||||
|
return association[association.type] === model;
|
||||||
|
});
|
||||||
|
|
||||||
if (!_.isEmpty(relationsToDelete)) {
|
if (!_.isEmpty(relationsToDelete)) {
|
||||||
// Retrieve where is located the model.
|
// Retrieve where is located the model.
|
||||||
@ -194,7 +200,9 @@ module.exports = {
|
|||||||
.filter(x => x.split('.settings.json')[0].toLowerCase() === name)[0];
|
.filter(x => x.split('.settings.json')[0].toLowerCase() === name)[0];
|
||||||
|
|
||||||
// Path to access to the model.
|
// Path to access to the model.
|
||||||
const pathToModel = path.join(strapi.config.appPath, 'api', target, 'models', filename);
|
const pathToModel = plugin ?
|
||||||
|
path.resolve(strapi.config.appPath, 'plugins', target, 'models', filename):
|
||||||
|
path.resolve(strapi.config.appPath, 'api', target, 'models', filename);
|
||||||
|
|
||||||
// Require the model.
|
// Require the model.
|
||||||
const modelJSON = require(pathToModel);
|
const modelJSON = require(pathToModel);
|
||||||
@ -220,15 +228,15 @@ module.exports = {
|
|||||||
// Update `./api` models.
|
// Update `./api` models.
|
||||||
deleteAssociations(structure.models);
|
deleteAssociations(structure.models);
|
||||||
|
|
||||||
// Object.keys(structure.plugins).forEach(name => {
|
Object.keys(structure.plugins).forEach(name => {
|
||||||
// // Update `./plugins/${name}` models.
|
// Update `./plugins/${name}` models.
|
||||||
// deleteAssociations(structure.plugins[name].models, name);
|
deleteAssociations(structure.plugins[name].models, name);
|
||||||
// });
|
});
|
||||||
|
|
||||||
return errors;
|
return errors;
|
||||||
},
|
},
|
||||||
|
|
||||||
createRelations: (model, attributes) => {
|
createRelations: (model, attributes, source) => {
|
||||||
const errors = [];
|
const errors = [];
|
||||||
const structure = {
|
const structure = {
|
||||||
models: strapi.models,
|
models: strapi.models,
|
||||||
@ -244,14 +252,12 @@ module.exports = {
|
|||||||
// Method to update the model
|
// Method to update the model
|
||||||
const update = (models, plugin) => {
|
const update = (models, plugin) => {
|
||||||
Object.keys(models).forEach(name => {
|
Object.keys(models).forEach(name => {
|
||||||
// TODO:
|
|
||||||
// - Retrieve right relation in plugin case.
|
|
||||||
const relationsToCreate = attributes.filter(attribute => {
|
const relationsToCreate = attributes.filter(attribute => {
|
||||||
if (!plugin) {
|
if (plugin) {
|
||||||
return _.get(attribute, 'params.target') === name && _.get(attribute, 'params.pluginValue', false) === false;
|
return _.get(attribute, 'params.target') === name && _.get(attribute, 'params.pluginValue') === plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _.get(attribute, 'params.target') === name && _.get(attribute, 'params.pluginValue', false) !== false;
|
return _.get(attribute, 'params.target') === name && _.isEmpty(_.get(attribute, 'params.pluginValue', ''));
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!_.isEmpty(relationsToCreate)) {
|
if (!_.isEmpty(relationsToCreate)) {
|
||||||
@ -264,15 +270,15 @@ module.exports = {
|
|||||||
.filter(x => x[0] !== '.')
|
.filter(x => x[0] !== '.')
|
||||||
.filter(x => x.split('.settings.json')[0].toLowerCase() === name)[0];
|
.filter(x => x.split('.settings.json')[0].toLowerCase() === name)[0];
|
||||||
|
|
||||||
const pathToModel = path.join(strapi.config.appPath, 'api', target, 'models', filename);
|
// Path to access to the model.
|
||||||
|
const pathToModel = plugin ?
|
||||||
|
path.resolve(strapi.config.appPath, 'plugins', target, 'models', filename):
|
||||||
|
path.resolve(strapi.config.appPath, 'api', target, 'models', filename);
|
||||||
|
|
||||||
const modelJSON = require(pathToModel);
|
const modelJSON = require(pathToModel);
|
||||||
|
|
||||||
_.forEach(relationsToCreate, ({ name, params }) => {
|
_.forEach(relationsToCreate, ({ name, params }) => {
|
||||||
const attr = {
|
const attr = {};
|
||||||
columnName: params.targetColumnName,
|
|
||||||
plugin: params.pluginValue
|
|
||||||
};
|
|
||||||
|
|
||||||
switch (params.nature) {
|
switch (params.nature) {
|
||||||
case 'oneToOne':
|
case 'oneToOne':
|
||||||
@ -287,6 +293,8 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
attr.via = name;
|
attr.via = name;
|
||||||
|
attr.columnName = params.targetColumnName;
|
||||||
|
attr.plugin = source;
|
||||||
|
|
||||||
modelJSON.attributes[params.key] = attr;
|
modelJSON.attributes[params.key] = attr;
|
||||||
|
|
||||||
@ -308,10 +316,10 @@ module.exports = {
|
|||||||
// Update `./api` models.
|
// Update `./api` models.
|
||||||
update(structure.models);
|
update(structure.models);
|
||||||
|
|
||||||
// Object.keys(structure.plugins).forEach(name => {
|
Object.keys(structure.plugins).forEach(name => {
|
||||||
// // Update `./plugins/${name}` models.
|
// Update `./plugins/${name}` models.
|
||||||
// update(structure.plugins[name].models, name);
|
update(structure.plugins[name].models, name);
|
||||||
// });
|
});
|
||||||
|
|
||||||
return errors;
|
return errors;
|
||||||
},
|
},
|
||||||
|
@ -28,5 +28,6 @@
|
|||||||
"role": {
|
"role": {
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"connection": "default"
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user