From 6ac1bca4176042bb9a1a8810d2e37e57b05a2720 Mon Sep 17 00:00:00 2001 From: Aurelsicoko Date: Sat, 16 Dec 2017 17:03:34 +0100 Subject: [PATCH] Update algorithm to correctly add, edit and delete relationships between models and plugins' models --- .../controllers/ContentTypeBuilder.js | 18 +++--- .../services/ContentTypeBuilder.js | 64 +++++++++++-------- .../models/User.settings.json | 5 +- 3 files changed, 49 insertions(+), 38 deletions(-) diff --git a/packages/strapi-plugin-content-type-builder/controllers/ContentTypeBuilder.js b/packages/strapi-plugin-content-type-builder/controllers/ContentTypeBuilder.js index 5dd1e83b53..b855eafc90 100755 --- a/packages/strapi-plugin-content-type-builder/controllers/ContentTypeBuilder.js +++ b/packages/strapi-plugin-content-type-builder/controllers/ContentTypeBuilder.js @@ -33,7 +33,7 @@ module.exports = { }, 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 (!_.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, []); - const modelFilePath = Service.getModelPath(name); + const modelFilePath = Service.getModelPath(name, plugin); try { - const modelJSON = require(modelFilePath); + const modelJSON = _.cloneDeep(require(modelFilePath)); modelJSON.attributes = formatedAttributes; - const clearRelationsErrors = Service.clearRelations(name); + const clearRelationsErrors = Service.clearRelations(name, plugin); if (!_.isEmpty(clearRelationsErrors)) { return ctx.badRequest(null, [{ messages: clearRelationsErrors }]); } - const createRelationsErrors = Service.createRelations(name, attributes); + const createRelationsErrors = Service.createRelations(name, attributes, plugin); if (!_.isEmpty(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(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 (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); @@ -108,7 +110,7 @@ module.exports = { } try { - const modelJSON = require(modelFilePath); + const modelJSON = _.cloneDeep(require(modelFilePath)); modelJSON.attributes = formatedAttributes; modelJSON.info = { @@ -118,13 +120,13 @@ module.exports = { modelJSON.connection = connection; modelJSON.collectionName = collectionName; - const clearRelationsErrors = Service.clearRelations(model); + const clearRelationsErrors = Service.clearRelations(model, plugin); if (!_.isEmpty(clearRelationsErrors)) { return ctx.badRequest(null, [{ messages: clearRelationsErrors }]); } - const createRelationsErrors = Service.createRelations(name, attributes); + const createRelationsErrors = Service.createRelations(name, attributes, plugin); if (!_.isEmpty(createRelationsErrors)) { return ctx.badRequest(null, [{ messages: createRelationsErrors }]); diff --git a/packages/strapi-plugin-content-type-builder/services/ContentTypeBuilder.js b/packages/strapi-plugin-content-type-builder/services/ContentTypeBuilder.js index 7caed1a180..56343d51d8 100755 --- a/packages/strapi-plugin-content-type-builder/services/ContentTypeBuilder.js +++ b/packages/strapi-plugin-content-type-builder/services/ContentTypeBuilder.js @@ -74,8 +74,6 @@ module.exports = { }, generateAPI: (name, description, connection, collectionName, attributes) => { - description = _.replace(description, /\"/g, '\\"'); - const template = _.get(strapi.config.currentEnvironment, `database.connections.${connection}.connector`, 'strapi-mongoose').split('-')[1]; return new Promise((resolve, reject) => { @@ -85,7 +83,7 @@ module.exports = { rootPath: strapi.config.appPath, args: { api: name, - description, + description: _.replace(description, /\"/g, '\\"'), attributes, connection, collectionName: !_.isEmpty(collectionName) ? collectionName : undefined, @@ -97,8 +95,8 @@ module.exports = { success: () => { resolve(); }, - error: () => { - reject(); + error: (err) => { + reject(err); } }); }); @@ -106,8 +104,9 @@ module.exports = { getModelPath: (model, plugin) => { // 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) || {}) - .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. 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.dominant = relation.dominant; + attr.plugin = relation.pluginValue; attrs[attribute.name] = attr; } @@ -165,7 +165,7 @@ module.exports = { return [attrs, errors]; }, - clearRelations: model => { + clearRelations: (model, source) => { const errors = []; const structure = { models: strapi.models, @@ -181,7 +181,13 @@ module.exports = { // Method to delete the association of the models. const deleteAssociations = (models, plugin) => { 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)) { // Retrieve where is located the model. @@ -194,7 +200,9 @@ module.exports = { .filter(x => x.split('.settings.json')[0].toLowerCase() === name)[0]; // 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. const modelJSON = require(pathToModel); @@ -220,15 +228,15 @@ module.exports = { // Update `./api` models. deleteAssociations(structure.models); - // Object.keys(structure.plugins).forEach(name => { - // // Update `./plugins/${name}` models. - // deleteAssociations(structure.plugins[name].models, name); - // }); + Object.keys(structure.plugins).forEach(name => { + // Update `./plugins/${name}` models. + deleteAssociations(structure.plugins[name].models, name); + }); return errors; }, - createRelations: (model, attributes) => { + createRelations: (model, attributes, source) => { const errors = []; const structure = { models: strapi.models, @@ -244,14 +252,12 @@ module.exports = { // Method to update the model const update = (models, plugin) => { Object.keys(models).forEach(name => { - // TODO: - // - Retrieve right relation in plugin case. const relationsToCreate = attributes.filter(attribute => { - if (!plugin) { - return _.get(attribute, 'params.target') === name && _.get(attribute, 'params.pluginValue', false) === false; + if (plugin) { + 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)) { @@ -264,15 +270,15 @@ module.exports = { .filter(x => x[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); _.forEach(relationsToCreate, ({ name, params }) => { - const attr = { - columnName: params.targetColumnName, - plugin: params.pluginValue - }; + const attr = {}; switch (params.nature) { case 'oneToOne': @@ -287,6 +293,8 @@ module.exports = { } attr.via = name; + attr.columnName = params.targetColumnName; + attr.plugin = source; modelJSON.attributes[params.key] = attr; @@ -308,10 +316,10 @@ module.exports = { // Update `./api` models. update(structure.models); - // Object.keys(structure.plugins).forEach(name => { - // // Update `./plugins/${name}` models. - // update(structure.plugins[name].models, name); - // }); + Object.keys(structure.plugins).forEach(name => { + // Update `./plugins/${name}` models. + update(structure.plugins[name].models, name); + }); return errors; }, diff --git a/packages/strapi-plugin-users-permissions/models/User.settings.json b/packages/strapi-plugin-users-permissions/models/User.settings.json index deef6b9210..879aaea08b 100644 --- a/packages/strapi-plugin-users-permissions/models/User.settings.json +++ b/packages/strapi-plugin-users-permissions/models/User.settings.json @@ -28,5 +28,6 @@ "role": { "type": "integer" } - } -} + }, + "connection": "default" +} \ No newline at end of file