From e273f7f76d4d96d31ee04ae5cc38c8f81644f479 Mon Sep 17 00:00:00 2001 From: Marc-Roig Date: Tue, 20 Dec 2022 10:17:38 +0100 Subject: [PATCH 1/9] look for duplicated inverseBy relationships --- packages/core/database/lib/index.js | 84 ++++++++++++++++++- .../core/database/lib/metadata/relations.js | 5 +- 2 files changed, 87 insertions(+), 2 deletions(-) diff --git a/packages/core/database/lib/index.js b/packages/core/database/lib/index.js index 3e003fcbf7..68859df4c8 100644 --- a/packages/core/database/lib/index.js +++ b/packages/core/database/lib/index.js @@ -11,6 +11,8 @@ const errors = require('./errors'); // TODO: move back into strapi const { transformContentTypes } = require('./utils/content-types'); +const { getJoinTableName } = require('./metadata/relations'); +const types = require('./types'); class Database { constructor(config) { @@ -72,9 +74,89 @@ class Database { } } +// TODO: Do the same for repeated mappedBy relations +const getLinks = ({ db }) => { + const relationsToUpdate = {}; + + db.metadata.forEach((contentType) => { + const attributes = contentType.attributes; + + // For each relation type, add the joinTable name to tablesToUpdate + Object.values(attributes).forEach((attribute) => { + if (!types.isRelation(attribute.type)) return; + + if (attribute.inversedBy) { + const invRelation = db.metadata.get(attribute.target).attributes[attribute.inversedBy]; + + // Both relations use inversedBy + if (invRelation?.inversedBy) { + relationsToUpdate[attribute.joinTable.name] = { + relation: attribute, + invRelation, + }; + } + } + }); + }); + + return Object.values(relationsToUpdate); +}; + +// const isLinkTableEmpty = async (db, linkTableName) => { +// const result = await db.getConnection().count('* as count').from(linkTableName); +// return result.count === 0; +// }; + // TODO: move into strapi Database.transformContentTypes = transformContentTypes; -Database.init = async (config) => new Database(config); +Database.init = async (config) => { + const db = new Database(config); + + // TODO: Create validations folder for this. + const links = getLinks({ db }); + + const errorList = []; + + for (const { relation, invRelation } of links) { + // Generate the join table name based on the relation target + // table and attribute name. + const joinTableName = getJoinTableName( + db.metadata.get(relation.target).tableName, + relation.inversedBy + ); + + const contentType = db.metadata.get(invRelation.target); + const invContentType = db.metadata.get(relation.target); + + // If both sides use inversedBy + // TODO: Same for mappedBy + if (relation.inversedBy && invRelation.inversedBy) { + // If the generated join table name is the same as the one assigned in relation.joinTable, + // relation is on the inversed side of the bidirectional relation. + // and the other is on the owner side. + if (joinTableName === relation.joinTable.name) { + errorList.push( + `Error on attribute "${invRelation.inversedBy}" in model "${invContentType.tableName}"(${invContentType.uid}):` + + ` One of the sides of the relationship must be the owning side. You should use mappedBy` + + ` instead of inversedBy in the relation "${invRelation.inversedBy}".` + ); + } else { + errorList.push( + `Error on attribute "${relation.inversedBy}" in model "${contentType.tableName}"(${contentType.uid}):` + + ` One of the sides of the relationship must be the owning side. You should use mappedBy` + + ` instead of inversedBy in the relation "${relation.inversedBy}".` + ); + } + } + } + + if (errorList.length > 0) { + errorList.forEach((error) => strapi.log.error(error)); + throw new Error('There are errors in some of your models. Please check the logs above.'); + } + + return db; +}; module.exports = { Database, diff --git a/packages/core/database/lib/metadata/relations.js b/packages/core/database/lib/metadata/relations.js index 5cdb2374b6..c3c051785f 100644 --- a/packages/core/database/lib/metadata/relations.js +++ b/packages/core/database/lib/metadata/relations.js @@ -16,6 +16,8 @@ const isAnyToMany = (attribute) => ['oneToMany', 'manyToMany'].includes(attribut const isBidirectional = (attribute) => hasInversedBy(attribute) || hasMappedBy(attribute); const isOwner = (attribute) => !isBidirectional(attribute) || hasInversedBy(attribute); const shouldUseJoinTable = (attribute) => attribute.useJoinTable !== false; +const getJoinTableName = (tableName, attributeName) => + _.snakeCase(`${tableName}_${attributeName}_links`); /** * Creates a oneToOne relation metadata @@ -397,7 +399,7 @@ const createJoinTable = (metadata, { attributeName, attribute, meta }) => { throw new Error(`Unknown target ${attribute.target}`); } - const joinTableName = _.snakeCase(`${meta.tableName}_${attributeName}_links`); + const joinTableName = getJoinTableName(meta.tableName, attributeName); const joinColumnName = _.snakeCase(`${meta.singularName}_id`); let inverseJoinColumnName = _.snakeCase(`${targetMeta.singularName}_id`); @@ -560,4 +562,5 @@ module.exports = { isAnyToMany, hasOrderColumn, hasInverseOrderColumn, + getJoinTableName, }; From 189a67b2377091590f19b45fea1f5b3b0bc24aac Mon Sep 17 00:00:00 2001 From: Marc-Roig Date: Tue, 20 Dec 2022 10:29:02 +0100 Subject: [PATCH 2/9] remove unnecessary comments --- packages/core/database/lib/index.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/packages/core/database/lib/index.js b/packages/core/database/lib/index.js index 68859df4c8..2407adf88d 100644 --- a/packages/core/database/lib/index.js +++ b/packages/core/database/lib/index.js @@ -74,7 +74,6 @@ class Database { } } -// TODO: Do the same for repeated mappedBy relations const getLinks = ({ db }) => { const relationsToUpdate = {}; @@ -102,11 +101,6 @@ const getLinks = ({ db }) => { return Object.values(relationsToUpdate); }; -// const isLinkTableEmpty = async (db, linkTableName) => { -// const result = await db.getConnection().count('* as count').from(linkTableName); -// return result.count === 0; -// }; - // TODO: move into strapi Database.transformContentTypes = transformContentTypes; Database.init = async (config) => { @@ -129,7 +123,6 @@ Database.init = async (config) => { const invContentType = db.metadata.get(relation.target); // If both sides use inversedBy - // TODO: Same for mappedBy if (relation.inversedBy && invRelation.inversedBy) { // If the generated join table name is the same as the one assigned in relation.joinTable, // relation is on the inversed side of the bidirectional relation. From 74c6ec1f6119375d47e60e1245835d7314d87b5d Mon Sep 17 00:00:00 2001 From: Marc-Roig Date: Mon, 2 Jan 2023 11:28:48 +0100 Subject: [PATCH 3/9] add validation folder in database --- packages/core/database/lib/index.js | 74 +------------- .../core/database/lib/validations/index.js | 20 ++++ .../validations/relations/bidirectional.js | 99 +++++++++++++++++++ .../lib/validations/relations/index.js | 14 +++ 4 files changed, 135 insertions(+), 72 deletions(-) create mode 100644 packages/core/database/lib/validations/index.js create mode 100644 packages/core/database/lib/validations/relations/bidirectional.js create mode 100644 packages/core/database/lib/validations/relations/index.js diff --git a/packages/core/database/lib/index.js b/packages/core/database/lib/index.js index 2407adf88d..7446c179f0 100644 --- a/packages/core/database/lib/index.js +++ b/packages/core/database/lib/index.js @@ -11,8 +11,7 @@ const errors = require('./errors'); // TODO: move back into strapi const { transformContentTypes } = require('./utils/content-types'); -const { getJoinTableName } = require('./metadata/relations'); -const types = require('./types'); +const { validateDatabase } = require('./validations'); class Database { constructor(config) { @@ -74,80 +73,11 @@ class Database { } } -const getLinks = ({ db }) => { - const relationsToUpdate = {}; - - db.metadata.forEach((contentType) => { - const attributes = contentType.attributes; - - // For each relation type, add the joinTable name to tablesToUpdate - Object.values(attributes).forEach((attribute) => { - if (!types.isRelation(attribute.type)) return; - - if (attribute.inversedBy) { - const invRelation = db.metadata.get(attribute.target).attributes[attribute.inversedBy]; - - // Both relations use inversedBy - if (invRelation?.inversedBy) { - relationsToUpdate[attribute.joinTable.name] = { - relation: attribute, - invRelation, - }; - } - } - }); - }); - - return Object.values(relationsToUpdate); -}; - // TODO: move into strapi Database.transformContentTypes = transformContentTypes; Database.init = async (config) => { const db = new Database(config); - - // TODO: Create validations folder for this. - const links = getLinks({ db }); - - const errorList = []; - - for (const { relation, invRelation } of links) { - // Generate the join table name based on the relation target - // table and attribute name. - const joinTableName = getJoinTableName( - db.metadata.get(relation.target).tableName, - relation.inversedBy - ); - - const contentType = db.metadata.get(invRelation.target); - const invContentType = db.metadata.get(relation.target); - - // If both sides use inversedBy - if (relation.inversedBy && invRelation.inversedBy) { - // If the generated join table name is the same as the one assigned in relation.joinTable, - // relation is on the inversed side of the bidirectional relation. - // and the other is on the owner side. - if (joinTableName === relation.joinTable.name) { - errorList.push( - `Error on attribute "${invRelation.inversedBy}" in model "${invContentType.tableName}"(${invContentType.uid}):` + - ` One of the sides of the relationship must be the owning side. You should use mappedBy` + - ` instead of inversedBy in the relation "${invRelation.inversedBy}".` - ); - } else { - errorList.push( - `Error on attribute "${relation.inversedBy}" in model "${contentType.tableName}"(${contentType.uid}):` + - ` One of the sides of the relationship must be the owning side. You should use mappedBy` + - ` instead of inversedBy in the relation "${relation.inversedBy}".` - ); - } - } - } - - if (errorList.length > 0) { - errorList.forEach((error) => strapi.log.error(error)); - throw new Error('There are errors in some of your models. Please check the logs above.'); - } - + await validateDatabase(db); return db; }; diff --git a/packages/core/database/lib/validations/index.js b/packages/core/database/lib/validations/index.js new file mode 100644 index 0000000000..a410331940 --- /dev/null +++ b/packages/core/database/lib/validations/index.js @@ -0,0 +1,20 @@ +'use strict'; + +const { validateRelations } = require('./relations'); + +/** + * Validate if the database is in a valid state before starting the server. + * + * @param {*} db - Database instance + */ +async function validateDatabase(db) { + const relationErrors = await validateRelations(db); + const errorList = [...relationErrors]; + + if (errorList.length > 0) { + errorList.forEach((error) => strapi.log.error(error)); + throw new Error('There are errors in some of your models. Please check the logs above.'); + } +} + +module.exports = { validateDatabase }; diff --git a/packages/core/database/lib/validations/relations/bidirectional.js b/packages/core/database/lib/validations/relations/bidirectional.js new file mode 100644 index 0000000000..b205e769ee --- /dev/null +++ b/packages/core/database/lib/validations/relations/bidirectional.js @@ -0,0 +1,99 @@ +'use strict'; + +const types = require('../../types'); +const { getJoinTableName } = require('../../metadata/relations'); + +const getLinksWithoutMappedBy = (db) => { + const relationsToUpdate = {}; + + db.metadata.forEach((contentType) => { + const attributes = contentType.attributes; + + // For each relation attribute, add the joinTable name to tablesToUpdate + Object.values(attributes).forEach((attribute) => { + if (!types.isRelation(attribute.type)) return; + + if (attribute.inversedBy) { + const invRelation = db.metadata.get(attribute.target).attributes[attribute.inversedBy]; + + // Both relations use inversedBy. + if (invRelation?.inversedBy) { + relationsToUpdate[attribute.joinTable.name] = { + relation: attribute, + invRelation, + }; + } + } + }); + }); + + return Object.values(relationsToUpdate); +}; + +const isLinkTableEmpty = async (db, linkTableName) => { + // If the table doesn't exist, it's empty + const exists = await db.getConnection().schema.hasTable(linkTableName); + if (!exists) return true; + + const result = await db.getConnection().count('* as count').from(linkTableName); + return result.count === 0; +}; + +/** + * Validates bidirectional relations before starting the server. + * - If both sides use inversedBy, one of the sides must switch to mappedBy. + * When this happens, two join tables exist in the database. + * This makes sure you switch the side which does not delete any data. + * + * @param {*} db + * @return {*} + */ +const validateBidirectionalRelations = async (db) => { + const invalidLinks = getLinksWithoutMappedBy(db); + const errorList = []; + + for (const { relation, invRelation } of invalidLinks) { + // Generate the join table name based on the relation target + // table and attribute name. + const inverseJoinTableName = getJoinTableName( + db.metadata.get(relation.target).tableName, + relation.inversedBy + ); + const joinTableName = getJoinTableName( + db.metadata.get(invRelation.target).tableName, + invRelation.inversedBy + ); + + const contentType = db.metadata.get(invRelation.target); + const invContentType = db.metadata.get(relation.target); + + // If both sides use inversedBy + if (relation.inversedBy && invRelation.inversedBy) { + const linkTableEmpty = await isLinkTableEmpty(db, joinTableName); + const inverseLinkTableEmpty = await isLinkTableEmpty(db, inverseJoinTableName); + + if (linkTableEmpty) { + errorList.push( + `Error on attribute "${relation.inversedBy}" in model "${contentType.tableName}"(${contentType.uid}):` + + ` One of the sides of the relationship must be the owning side. You should use mappedBy` + + ` instead of inversedBy in the relation "${relation.inversedBy}".` + ); + } else if (inverseLinkTableEmpty) { + // Its safe to delete the inverse join table + errorList.push( + `Error on attribute "${invRelation.inversedBy}" in model "${invContentType.tableName}"(${invContentType.uid}):` + + ` One of the sides of the relationship must be the owning side. You should use mappedBy` + + ` instead of inversedBy in the relation "${invRelation.inversedBy}".` + ); + } else { + // Both sides have data in the join table + } + } + } + + return errorList; +}; + +module.exports = { + validateBidirectionalRelations, +}; diff --git a/packages/core/database/lib/validations/relations/index.js b/packages/core/database/lib/validations/relations/index.js new file mode 100644 index 0000000000..02e8cffc93 --- /dev/null +++ b/packages/core/database/lib/validations/relations/index.js @@ -0,0 +1,14 @@ +'use strict'; + +const { validateBidirectionalRelations } = require('./bidirectional'); + +/** + * Validates if relations data and tables are in a valid state before + * starting the server. + */ +const validateRelations = async (db) => { + const bidirectionalRelationsErrors = await validateBidirectionalRelations(db); + return [...bidirectionalRelationsErrors]; +}; + +module.exports = { validateRelations }; From 37ff580b1d3bf7199f867b676098bd582ab5c179 Mon Sep 17 00:00:00 2001 From: Marc-Roig Date: Wed, 11 Jan 2023 11:51:54 +0100 Subject: [PATCH 4/9] change error to warning --- .../validations/relations/bidirectional.js | 56 ++++++++----------- 1 file changed, 23 insertions(+), 33 deletions(-) diff --git a/packages/core/database/lib/validations/relations/bidirectional.js b/packages/core/database/lib/validations/relations/bidirectional.js index b205e769ee..cca55bc0ae 100644 --- a/packages/core/database/lib/validations/relations/bidirectional.js +++ b/packages/core/database/lib/validations/relations/bidirectional.js @@ -17,7 +17,7 @@ const getLinksWithoutMappedBy = (db) => { const invRelation = db.metadata.get(attribute.target).attributes[attribute.inversedBy]; // Both relations use inversedBy. - if (invRelation?.inversedBy) { + if (invRelation.inversedBy) { relationsToUpdate[attribute.joinTable.name] = { relation: attribute, invRelation, @@ -36,7 +36,7 @@ const isLinkTableEmpty = async (db, linkTableName) => { if (!exists) return true; const result = await db.getConnection().count('* as count').from(linkTableName); - return result.count === 0; + return Number(result[0].count) === 0; }; /** @@ -53,41 +53,31 @@ const validateBidirectionalRelations = async (db) => { const errorList = []; for (const { relation, invRelation } of invalidLinks) { - // Generate the join table name based on the relation target - // table and attribute name. - const inverseJoinTableName = getJoinTableName( - db.metadata.get(relation.target).tableName, - relation.inversedBy - ); - const joinTableName = getJoinTableName( - db.metadata.get(invRelation.target).tableName, - invRelation.inversedBy - ); - const contentType = db.metadata.get(invRelation.target); const invContentType = db.metadata.get(relation.target); - // If both sides use inversedBy - if (relation.inversedBy && invRelation.inversedBy) { - const linkTableEmpty = await isLinkTableEmpty(db, joinTableName); - const inverseLinkTableEmpty = await isLinkTableEmpty(db, inverseJoinTableName); + // Generate the join table name based on the relation target table and attribute name. + const joinTableName = getJoinTableName(contentType.tableName, invRelation.inversedBy); + const inverseJoinTableName = getJoinTableName(invContentType.tableName, relation.inversedBy); - if (linkTableEmpty) { - errorList.push( - `Error on attribute "${relation.inversedBy}" in model "${contentType.tableName}"(${contentType.uid}):` + - ` One of the sides of the relationship must be the owning side. You should use mappedBy` + - ` instead of inversedBy in the relation "${relation.inversedBy}".` - ); - } else if (inverseLinkTableEmpty) { - // Its safe to delete the inverse join table - errorList.push( - `Error on attribute "${invRelation.inversedBy}" in model "${invContentType.tableName}"(${invContentType.uid}):` + - ` One of the sides of the relationship must be the owning side. You should use mappedBy` + - ` instead of inversedBy in the relation "${invRelation.inversedBy}".` - ); - } else { - // Both sides have data in the join table - } + const joinTableEmpty = await isLinkTableEmpty(db, joinTableName); + const inverseJoinTableEmpty = await isLinkTableEmpty(db, inverseJoinTableName); + + if (joinTableEmpty) { + process.emitWarning( + `Error on attribute "${relation.inversedBy}" in model "${contentType.singularName}" (${contentType.uid}).` + + ` Please modify your schema by renaming the key inversedBy by mappedBy.` + + ` Ex: { inversedBy: "${relation.inversedBy}" } -> { mappedBy: "${relation.inversedBy}" } }` + ); + } else if (inverseJoinTableEmpty) { + // Its safe to delete the inverse join table + process.emitWarning( + `Error on attribute "${invRelation.inversedBy}" in model "${invContentType.singularName}" (${invContentType.uid}).` + + ` Please modify your schema by renaming the key inversedBy by mappedBy.` + + ` Ex: { inversedBy: "${invRelation.inversedBy}" } -> { mappedBy: "${invRelation.inversedBy}" } }` + ); + } else { + // Both sides have data in the join table } } From 1ef6230f20c304764ca53ab077fc61c820cde1e8 Mon Sep 17 00:00:00 2001 From: Marc-Roig Date: Wed, 11 Jan 2023 13:55:45 +0100 Subject: [PATCH 5/9] change attribute name displayed in warning --- .../core/database/lib/validations/relations/bidirectional.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/database/lib/validations/relations/bidirectional.js b/packages/core/database/lib/validations/relations/bidirectional.js index cca55bc0ae..6d41db2da4 100644 --- a/packages/core/database/lib/validations/relations/bidirectional.js +++ b/packages/core/database/lib/validations/relations/bidirectional.js @@ -65,14 +65,14 @@ const validateBidirectionalRelations = async (db) => { if (joinTableEmpty) { process.emitWarning( - `Error on attribute "${relation.inversedBy}" in model "${contentType.singularName}" (${contentType.uid}).` + + `Error on attribute "${invRelation.inversedBy}" in model "${contentType.singularName}" (${contentType.uid}).` + ` Please modify your schema by renaming the key inversedBy by mappedBy.` + ` Ex: { inversedBy: "${relation.inversedBy}" } -> { mappedBy: "${relation.inversedBy}" } }` ); } else if (inverseJoinTableEmpty) { // Its safe to delete the inverse join table process.emitWarning( - `Error on attribute "${invRelation.inversedBy}" in model "${invContentType.singularName}" (${invContentType.uid}).` + + `Error on attribute "${relation.inversedBy}" in model "${invContentType.singularName}" (${invContentType.uid}).` + ` Please modify your schema by renaming the key inversedBy by mappedBy.` + ` Ex: { inversedBy: "${invRelation.inversedBy}" } -> { mappedBy: "${invRelation.inversedBy}" } }` ); From 003b0094554d798ee7f88f3492bb4b0701450a9b Mon Sep 17 00:00:00 2001 From: Marc-Roig Date: Wed, 18 Jan 2023 16:54:03 +0100 Subject: [PATCH 6/9] specify content type schema name --- .../core/database/lib/validations/relations/bidirectional.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/database/lib/validations/relations/bidirectional.js b/packages/core/database/lib/validations/relations/bidirectional.js index 6d41db2da4..75ed3bfca8 100644 --- a/packages/core/database/lib/validations/relations/bidirectional.js +++ b/packages/core/database/lib/validations/relations/bidirectional.js @@ -66,14 +66,14 @@ const validateBidirectionalRelations = async (db) => { if (joinTableEmpty) { process.emitWarning( `Error on attribute "${invRelation.inversedBy}" in model "${contentType.singularName}" (${contentType.uid}).` + - ` Please modify your schema by renaming the key inversedBy by mappedBy.` + + ` Please modify your ${contentType.singularName} schema by renaming the key inversedBy by mappedBy.` + ` Ex: { inversedBy: "${relation.inversedBy}" } -> { mappedBy: "${relation.inversedBy}" } }` ); } else if (inverseJoinTableEmpty) { // Its safe to delete the inverse join table process.emitWarning( `Error on attribute "${relation.inversedBy}" in model "${invContentType.singularName}" (${invContentType.uid}).` + - ` Please modify your schema by renaming the key inversedBy by mappedBy.` + + ` Please modify your ${invContentType.singularName} schema by renaming the key inversedBy by mappedBy.` + ` Ex: { inversedBy: "${invRelation.inversedBy}" } -> { mappedBy: "${invRelation.inversedBy}" } }` ); } else { From 52b780b0362a8f3e7d0f49b85597bfcbdbb69d80 Mon Sep 17 00:00:00 2001 From: Marc-Roig Date: Wed, 18 Jan 2023 17:11:27 +0100 Subject: [PATCH 7/9] add quotes in inversedBy and mappedBy --- .../core/database/lib/validations/relations/bidirectional.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/database/lib/validations/relations/bidirectional.js b/packages/core/database/lib/validations/relations/bidirectional.js index 75ed3bfca8..013b1ec345 100644 --- a/packages/core/database/lib/validations/relations/bidirectional.js +++ b/packages/core/database/lib/validations/relations/bidirectional.js @@ -66,14 +66,14 @@ const validateBidirectionalRelations = async (db) => { if (joinTableEmpty) { process.emitWarning( `Error on attribute "${invRelation.inversedBy}" in model "${contentType.singularName}" (${contentType.uid}).` + - ` Please modify your ${contentType.singularName} schema by renaming the key inversedBy by mappedBy.` + + ` Please modify your ${contentType.singularName} schema by renaming the key "inversedBy" by "mappedBy".` + ` Ex: { inversedBy: "${relation.inversedBy}" } -> { mappedBy: "${relation.inversedBy}" } }` ); } else if (inverseJoinTableEmpty) { // Its safe to delete the inverse join table process.emitWarning( `Error on attribute "${relation.inversedBy}" in model "${invContentType.singularName}" (${invContentType.uid}).` + - ` Please modify your ${invContentType.singularName} schema by renaming the key inversedBy by mappedBy.` + + ` Please modify your ${invContentType.singularName} schema by renaming the key "inversedBy" by "mappedBy".` + ` Ex: { inversedBy: "${invRelation.inversedBy}" } -> { mappedBy: "${invRelation.inversedBy}" } }` ); } else { From bc53362e162f3e027091a22fc833623a8076e08f Mon Sep 17 00:00:00 2001 From: Marc-Roig Date: Wed, 18 Jan 2023 17:13:33 +0100 Subject: [PATCH 8/9] fix typo --- .../core/database/lib/validations/relations/bidirectional.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/database/lib/validations/relations/bidirectional.js b/packages/core/database/lib/validations/relations/bidirectional.js index 013b1ec345..6240e53c1d 100644 --- a/packages/core/database/lib/validations/relations/bidirectional.js +++ b/packages/core/database/lib/validations/relations/bidirectional.js @@ -66,14 +66,14 @@ const validateBidirectionalRelations = async (db) => { if (joinTableEmpty) { process.emitWarning( `Error on attribute "${invRelation.inversedBy}" in model "${contentType.singularName}" (${contentType.uid}).` + - ` Please modify your ${contentType.singularName} schema by renaming the key "inversedBy" by "mappedBy".` + + ` Please modify your ${contentType.singularName} schema by renaming the key "inversedBy" to "mappedBy".` + ` Ex: { inversedBy: "${relation.inversedBy}" } -> { mappedBy: "${relation.inversedBy}" } }` ); } else if (inverseJoinTableEmpty) { // Its safe to delete the inverse join table process.emitWarning( `Error on attribute "${relation.inversedBy}" in model "${invContentType.singularName}" (${invContentType.uid}).` + - ` Please modify your ${invContentType.singularName} schema by renaming the key "inversedBy" by "mappedBy".` + + ` Please modify your ${invContentType.singularName} schema by renaming the key "inversedBy" to "mappedBy".` + ` Ex: { inversedBy: "${invRelation.inversedBy}" } -> { mappedBy: "${invRelation.inversedBy}" } }` ); } else { From d2636e58d6190d170ac0906279f1d630986b08d7 Mon Sep 17 00:00:00 2001 From: Marc-Roig Date: Wed, 18 Jan 2023 17:19:01 +0100 Subject: [PATCH 9/9] fix typo --- .../core/database/lib/validations/relations/bidirectional.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/database/lib/validations/relations/bidirectional.js b/packages/core/database/lib/validations/relations/bidirectional.js index 6240e53c1d..4da9a271ff 100644 --- a/packages/core/database/lib/validations/relations/bidirectional.js +++ b/packages/core/database/lib/validations/relations/bidirectional.js @@ -67,14 +67,14 @@ const validateBidirectionalRelations = async (db) => { process.emitWarning( `Error on attribute "${invRelation.inversedBy}" in model "${contentType.singularName}" (${contentType.uid}).` + ` Please modify your ${contentType.singularName} schema by renaming the key "inversedBy" to "mappedBy".` + - ` Ex: { inversedBy: "${relation.inversedBy}" } -> { mappedBy: "${relation.inversedBy}" } }` + ` Ex: { "inversedBy": "${relation.inversedBy}" } -> { "mappedBy": "${relation.inversedBy}" }` ); } else if (inverseJoinTableEmpty) { // Its safe to delete the inverse join table process.emitWarning( `Error on attribute "${relation.inversedBy}" in model "${invContentType.singularName}" (${invContentType.uid}).` + ` Please modify your ${invContentType.singularName} schema by renaming the key "inversedBy" to "mappedBy".` + - ` Ex: { inversedBy: "${invRelation.inversedBy}" } -> { mappedBy: "${invRelation.inversedBy}" } }` + ` Ex: { "inversedBy": "${invRelation.inversedBy}" } -> { "mappedBy": "${invRelation.inversedBy}" }` ); } else { // Both sides have data in the join table