Merge pull request #21129 from strapi/fix/self-ref-rel

fix: reproduce v4 behavior for data compatibility
This commit is contained in:
Alexandre BODIN 2024-09-02 17:10:58 +02:00 committed by GitHub
commit 6fbc0e990c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 124 additions and 10 deletions

View File

@ -120,7 +120,18 @@ export default function createComponentBuilder() {
if (isRelation(attribute)) {
if (['manyToMany', 'oneToOne'].includes(attribute.relation)) {
attribute.dominant = true;
if (attribute.target === uid && attribute.targetAttribute !== undefined) {
// self referencing relation
const targetAttribute = infos.attributes[attribute.targetAttribute];
if (targetAttribute.dominant === undefined) {
attribute.dominant = true;
} else {
attribute.dominant = false;
}
} else {
attribute.dominant = true;
}
}
this.setRelation({
@ -214,7 +225,18 @@ export default function createComponentBuilder() {
if (isRelation(attribute)) {
if (['manyToMany', 'oneToOne'].includes(attribute.relation)) {
attribute.dominant = true;
if (attribute.target === uid && attribute.targetAttribute !== undefined) {
// self referencing relation
const targetAttribute = newAttributes[attribute.targetAttribute];
if (targetAttribute.dominant === undefined) {
attribute.dominant = true;
} else {
attribute.dominant = false;
}
} else {
attribute.dominant = true;
}
}
this.setRelation({

View File

@ -55,6 +55,7 @@ export const expectedMetadataHashedResults = {
relation: 'oneToOne',
target: 'api::complex.complex',
joinTable: {
__internal__: true,
name: 'complexes_comple5354f_lnk',
joinColumn: {
name: 'complex_id',
@ -202,6 +203,7 @@ export const expectedMetadataHashedResults = {
target: 'api::complex.complex',
inversedBy: 'complexes',
joinTable: {
__internal__: true,
name: 'complexes_comple3e8ce_lnk',
joinColumn: {
name: 'complex_id',
@ -223,6 +225,7 @@ export const expectedMetadataHashedResults = {
target: 'api::complex.complex',
mappedBy: 'complexeshasandbelongstomanycomplexes',
joinTable: {
__internal__: true,
name: 'complexes_comple3e8ce_lnk',
joinColumn: {
name: 'inv_complex_id',
@ -354,6 +357,7 @@ export const expectedMetadataHashedResults = {
target: 'api::complex.complex',
inversedBy: 'complex',
joinTable: {
__internal__: true,
name: 'complexes_comple64178_lnk',
joinColumn: {
name: 'complex_id',
@ -370,10 +374,11 @@ export const expectedMetadataHashedResults = {
},
complex: {
type: 'relation',
relation: 'manyToOne',
relation: 'oneToOne',
target: 'api::complex.complex',
inversedBy: 'complexbelongstomanycomplexes',
mappedBy: 'complexhasandbelongstoonecomplex',
joinTable: {
__internal__: true,
name: 'complexes_comple64178_lnk',
joinColumn: {
name: 'inv_complex_id',
@ -488,6 +493,7 @@ export const expectedMetadataHashedResults = {
target: 'api::complex.complex',
inversedBy: 'complexes',
joinTable: {
__internal__: true,
name: 'complexes_comple61dc1_lnk',
joinColumn: {
name: 'complex_id',
@ -513,6 +519,7 @@ export const expectedMetadataHashedResults = {
target: 'api::complex.complex',
mappedBy: 'complexeshasandbelongstomanycomplexes',
joinTable: {
__internal__: true,
name: 'complexes_comple61dc1_lnk',
joinColumn: {
name: 'inv_complex_id',
@ -659,6 +666,7 @@ export const expectedMetadataHashedResults = {
relation: 'oneToOne',
target: 'api::complex.complex',
joinTable: {
__internal__: true,
name: 'componen56bca_complex_lnk',
joinColumn: {
name: 'long_component_name_id',
@ -678,6 +686,7 @@ export const expectedMetadataHashedResults = {
relation: 'oneToMany',
target: 'api::complex.complex',
joinTable: {
__internal__: true,
name: 'compon56bca_complexes_lnk',
joinColumn: {
name: 'long_component_name_id',
@ -923,6 +932,7 @@ export const expectedMetadataHashedResults = {
relation: 'oneToOne',
target: 'api::complex.complex',
joinTable: {
__internal__: true,
name: 'componen56bca_complex_lnk',
joinColumn: {
name: 'long_component_name_id',
@ -942,6 +952,7 @@ export const expectedMetadataHashedResults = {
relation: 'oneToMany',
target: 'api::complex.complex',
joinTable: {
__internal__: true,
name: 'compon56bca_complexes_lnk',
joinColumn: {
name: 'long_component_name_id',
@ -1188,6 +1199,7 @@ export const expectedMetadataHashedResults = {
relation: 'oneToOne',
target: 'api::complex.complex',
joinTable: {
__internal__: true,
name: 'componen56bca_complex_lnk',
joinColumn: {
name: 'long_component_name_id',
@ -1207,6 +1219,7 @@ export const expectedMetadataHashedResults = {
relation: 'oneToMany',
target: 'api::complex.complex',
joinTable: {
__internal__: true,
name: 'compon56bca_complexes_lnk',
joinColumn: {
name: 'long_component_name_id',

View File

@ -79,6 +79,7 @@ export const expectedMetadataResults = {
relation: 'oneToOne',
target: 'api::complex.complex',
joinTable: {
__internal__: true,
name: 'complexes_complexhasonecomplex_links',
joinColumn: {
name: 'complex_id',
@ -226,6 +227,7 @@ export const expectedMetadataResults = {
target: 'api::complex.complex',
inversedBy: 'complexes',
joinTable: {
__internal__: true,
name: 'complexes_complexhasmanycomplexes_links',
joinColumn: {
name: 'complex_id',
@ -247,6 +249,7 @@ export const expectedMetadataResults = {
target: 'api::complex.complex',
mappedBy: 'complexeshasandbelongstomanycomplexes',
joinTable: {
__internal__: true,
name: 'complexes_complexhasmanycomplexes_links',
joinColumn: {
name: 'inv_complex_id',
@ -378,6 +381,7 @@ export const expectedMetadataResults = {
target: 'api::complex.complex',
inversedBy: 'complex',
joinTable: {
__internal__: true,
name: 'complexes_complexhasandbelongstoonecomplex_links',
joinColumn: {
name: 'complex_id',
@ -394,10 +398,11 @@ export const expectedMetadataResults = {
},
complex: {
type: 'relation',
relation: 'manyToOne',
relation: 'oneToOne',
target: 'api::complex.complex',
inversedBy: 'complexbelongstomanycomplexes',
mappedBy: 'complexhasandbelongstoonecomplex',
joinTable: {
__internal__: true,
name: 'complexes_complexhasandbelongstoonecomplex_links',
joinColumn: {
name: 'inv_complex_id',
@ -512,6 +517,7 @@ export const expectedMetadataResults = {
target: 'api::complex.complex',
inversedBy: 'complexes',
joinTable: {
__internal__: true,
name: 'complexes_complexeshasandbelongstomanycomplexes_links',
joinColumn: {
name: 'complex_id',
@ -537,6 +543,7 @@ export const expectedMetadataResults = {
target: 'api::complex.complex',
mappedBy: 'complexeshasandbelongstomanycomplexes',
joinTable: {
__internal__: true,
name: 'complexes_complexeshasandbelongstomanycomplexes_links',
joinColumn: {
name: 'inv_complex_id',
@ -681,6 +688,7 @@ export const expectedMetadataResults = {
relation: 'oneToOne',
target: 'api::complex.complex',
joinTable: {
__internal__: true,
name: 'components_default_long_component_names_complex_links',
joinColumn: {
name: 'long_component_name_id',
@ -700,6 +708,7 @@ export const expectedMetadataResults = {
relation: 'oneToMany',
target: 'api::complex.complex',
joinTable: {
__internal__: true,
name: 'components_default_long_component_names_complexes_links',
joinColumn: {
name: 'long_component_name_id',
@ -946,6 +955,7 @@ export const expectedMetadataResults = {
relation: 'oneToOne',
target: 'api::complex.complex',
joinTable: {
__internal__: true,
name: 'components_default_long_component_names_complex_links',
joinColumn: {
name: 'long_component_name_id',
@ -965,6 +975,7 @@ export const expectedMetadataResults = {
relation: 'oneToMany',
target: 'api::complex.complex',
joinTable: {
__internal__: true,
name: 'components_default_long_component_names_complexes_links',
joinColumn: {
name: 'long_component_name_id',
@ -1210,6 +1221,7 @@ export const expectedMetadataResults = {
relation: 'oneToOne',
target: 'api::complex.complex',
joinTable: {
__internal__: true,
name: 'components_default_long_component_names_complex_links',
joinColumn: {
name: 'long_component_name_id',
@ -1229,6 +1241,7 @@ export const expectedMetadataResults = {
relation: 'oneToMany',
target: 'api::complex.complex',
joinTable: {
__internal__: true,
name: 'components_default_long_component_names_complexes_links',
joinColumn: {
name: 'long_component_name_id',
@ -1475,6 +1488,7 @@ export const expectedMetadataResults = {
relation: 'oneToOne',
target: 'api::complex.complex',
joinTable: {
__internal__: true,
name: 'components_default_long_component_names_complex_links',
joinColumn: {
name: 'long_component_name_id',
@ -1494,6 +1508,7 @@ export const expectedMetadataResults = {
relation: 'oneToMany',
target: 'api::complex.complex',
joinTable: {
__internal__: true,
name: 'components_default_long_component_names_complexes_links',
joinColumn: {
name: 'long_component_name_id',

View File

@ -83,9 +83,9 @@ export const attributes = {
},
complex: {
type: 'relation',
relation: 'manyToOne',
relation: 'oneToOne',
target: 'api::complex.complex',
inversedBy: 'complexbelongstomanycomplexes',
mappedBy: 'complexhasandbelongstoonecomplex',
},
},
manyToMany: {

View File

@ -237,7 +237,7 @@ const createMorphToMany = (
meta: Meta,
metadata: Metadata
) => {
if ('joinTable' in attribute && attribute.joinTable) {
if ('joinTable' in attribute && attribute.joinTable && !attribute.joinTable.__internal__) {
return;
}
@ -311,6 +311,7 @@ const createMorphToMany = (
});
const joinTable: MorphJoinTable = {
__internal__: true,
name: joinTableName,
joinColumn: {
name: joinColumnName,
@ -423,7 +424,7 @@ const createJoinTable = (
}
// TODO: implement overwrite logic instead
if ('joinTable' in attribute && attribute.joinTable) {
if ('joinTable' in attribute && attribute.joinTable && !attribute.joinTable.__internal__) {
return;
}
@ -519,6 +520,7 @@ const createJoinTable = (
};
const joinTable = {
__internal__: true,
name: joinTableName,
joinColumn: {
name: joinColumnName,
@ -592,6 +594,7 @@ const createJoinTable = (
}
inverseAttribute.joinTable = {
__internal__: true,
name: joinTableName,
joinColumn: joinTable.inverseJoinColumn,
inverseJoinColumn: joinTable.joinColumn,

View File

@ -79,6 +79,11 @@ export interface BaseJoinTable {
referencedColumn: string;
referencedTable?: string;
};
/**
* Use to flag joinTable we created internally vs user defined
* @internal
*/
__internal__?: boolean;
}
export interface JoinTable extends BaseJoinTable {
@ -194,6 +199,12 @@ export interface MorphJoinTable {
on?: Record<string, unknown>;
pivotColumns: string[];
morphColumn: MorphColumn;
/**
* Use to flag joinTable we created internally vs user defined
* @internal
*/
__internal__?: boolean;
}
export interface BaseRelationalAttribute {

View File

@ -0,0 +1,50 @@
'use strict';
// Test an API with all the possible filed types and simple filterings (no deep filtering, no relations)
const { createStrapiInstance } = require('api-tests/strapi');
const { createTestBuilder } = require('api-tests/builder');
const builder = createTestBuilder();
let strapi;
const testCT = {
displayName: 'test',
singularName: 'test',
pluralName: 'tests',
kind: 'collectionType',
attributes: {
children: {
type: 'relation',
relation: 'manyToMany',
target: 'api::test.test',
inversedBy: 'parents',
},
parents: {
type: 'relation',
relation: 'manyToMany',
target: 'api::test.test',
inversedBy: 'children', // intentionally wrong to validate retro compatibility
},
},
};
describe('v4-self-ref-compat', () => {
beforeAll(async () => {
await builder.addContentType(testCT).build();
strapi = await createStrapiInstance();
});
afterAll(async () => {
await strapi.destroy();
await builder.cleanup();
});
test('2 tables are created', async () => {
const hasFirstTable = await strapi.db.getConnection().schema.hasTable('tests_children_lnk');
const hasSecondTable = await strapi.db.getConnection().schema.hasTable('tests_parents_lnk');
expect(hasFirstTable).toBe(true);
expect(hasSecondTable).toBe(true);
});
});