chore: remove belongsToMany through table as collection dependency (#2289)

Co-authored-by: chenos <chenlinxh@gmail.com>
This commit is contained in:
ChengLei Shao 2023-07-21 12:18:17 +08:00 committed by GitHub
parent 8196e164a5
commit fe2890f9ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 14 additions and 16 deletions

View File

@ -46,7 +46,7 @@ export class RoleResourceActionModel extends Model {
const collectionField = collection.getField(field); const collectionField = collection.getField(field);
if (!collectionField) { if (!collectionField) {
console.log(`${field} does not exist`); console.log(`field ${field} does not exist at ${collection.name}`);
continue; continue;
} }

View File

@ -1,7 +1,6 @@
import { Repository } from '@nocobase/database'; import { Repository } from '@nocobase/database';
import { CollectionsGraph } from '@nocobase/utils'; import { CollectionsGraph, lodash } from '@nocobase/utils';
import { CollectionModel } from '../models/collection'; import { CollectionModel } from '../models/collection';
import { lodash } from '@nocobase/utils';
interface LoadOptions { interface LoadOptions {
filter?: any; filter?: any;
@ -23,6 +22,7 @@ export class CollectionRepository extends Repository {
const viewCollections = []; const viewCollections = [];
// set all graph nodes
for (const instance of instances) { for (const instance of instances) {
graph.setNode(instance.get('name')); graph.setNode(instance.get('name'));
if (instance.get('view')) { if (instance.get('view')) {
@ -30,23 +30,12 @@ export class CollectionRepository extends Repository {
} }
} }
// set graph edges by inherits
for (const instance of instances) { for (const instance of instances) {
const collectionName = instance.get('name'); const collectionName = instance.get('name');
nameMap[collectionName] = instance; nameMap[collectionName] = instance;
// @ts-ignore
const fields = instance.get('fields') || [];
for (const field of fields) {
if (field['type'] === 'belongsToMany') {
const throughName = field.options.through;
if (throughName) {
graph.setEdge(throughName, collectionName);
graph.setEdge(throughName, field.options.target);
}
}
}
if (instance.get('inherits')) { if (instance.get('inherits')) {
for (const parent of instance.get('inherits')) { for (const parent of instance.get('inherits')) {
graph.setEdge(parent, collectionName); graph.setEdge(parent, collectionName);
@ -56,20 +45,25 @@ export class CollectionRepository extends Repository {
if (graph.nodeCount() === 0) return; if (graph.nodeCount() === 0) return;
// check if graph is acyclic, throw error if not
if (!graphlib.alg.isAcyclic(graph)) { if (!graphlib.alg.isAcyclic(graph)) {
const cycles = graphlib.alg.findCycles(graph); const cycles = graphlib.alg.findCycles(graph);
throw new Error(`Cyclic dependencies: ${cycles.map((cycle) => cycle.join(' -> ')).join(', ')}`); throw new Error(`Cyclic dependencies: ${cycles.map((cycle) => cycle.join(' -> ')).join(', ')}`);
} }
// sort graph nodes
const sortedNames = graphlib.alg.topsort(graph); const sortedNames = graphlib.alg.topsort(graph);
const lazyCollectionFields: { const lazyCollectionFields: {
[key: string]: Array<string>; [key: string]: Array<string>;
} = {}; } = {};
for (const instanceName of sortedNames) { for (const instanceName of sortedNames) {
if (!nameMap[instanceName]) continue; if (!nameMap[instanceName]) continue;
// skip load collection field
const skipField = (() => { const skipField = (() => {
// skip load collection field if collection is view
if (viewCollections.includes(instanceName)) { if (viewCollections.includes(instanceName)) {
return true; return true;
} }
@ -77,7 +71,11 @@ export class CollectionRepository extends Repository {
const fields = nameMap[instanceName].get('fields'); const fields = nameMap[instanceName].get('fields');
return fields return fields
.filter((field) => field['type'] === 'belongsTo' && viewCollections.includes(field.options?.['target'])) .filter(
(field) =>
(field['type'] === 'belongsTo' && viewCollections.includes(field.options?.['target'])) ||
field['type'] === 'belongsToMany',
)
.map((field) => field.get('name')); .map((field) => field.get('name'));
})(); })();