mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-05 13:39:24 +08:00
83 lines
2.5 KiB
TypeScript
83 lines
2.5 KiB
TypeScript
import { omit } from 'lodash';
|
|
import { BelongsToOptions as SequelizeBelongsToOptions, Utils } from 'sequelize';
|
|
import { BaseRelationFieldOptions, RelationField } from './relation-field';
|
|
import { checkIdentifier } from '../utils';
|
|
|
|
export class BelongsToField extends RelationField {
|
|
static type = 'belongsTo';
|
|
|
|
get target() {
|
|
const { target, name } = this.options;
|
|
return target || Utils.pluralize(name);
|
|
}
|
|
|
|
bind() {
|
|
const { database, collection } = this.context;
|
|
const Target = this.TargetModel;
|
|
|
|
// if target model not exists, add it to pending field,
|
|
// it will bind later
|
|
if (!Target) {
|
|
database.addPendingField(this);
|
|
return false;
|
|
}
|
|
|
|
if (collection.model.associations[this.name]) {
|
|
delete collection.model.associations[this.name];
|
|
}
|
|
|
|
// define relation on sequelize model
|
|
const association = collection.model.belongsTo(Target, {
|
|
as: this.name,
|
|
constraints: false,
|
|
...omit(this.options, ['name', 'type', 'target']),
|
|
});
|
|
|
|
// inverse relation
|
|
// this.TargetModel.hasMany(collection.model);
|
|
|
|
// 建立关系之后从 pending 列表中删除
|
|
database.removePendingField(this);
|
|
|
|
if (!this.options.foreignKey) {
|
|
this.options.foreignKey = association.foreignKey;
|
|
}
|
|
|
|
checkIdentifier(this.options.foreignKey);
|
|
|
|
if (!this.options.sourceKey) {
|
|
// @ts-ignore
|
|
this.options.sourceKey = association.sourceKey;
|
|
}
|
|
|
|
this.collection.addIndex([this.options.foreignKey]);
|
|
return true;
|
|
}
|
|
|
|
unbind() {
|
|
const { database, collection } = this.context;
|
|
// 如果关系字段还没建立就删除了,也同步删除待建立关联的关系字段
|
|
database.removePendingField(this);
|
|
// 如果外键没有显式的创建,关系表也无反向关联字段,删除关系时,外键也删除掉
|
|
const tcoll = database.collections.get(this.target);
|
|
const foreignKey = this.options.foreignKey;
|
|
const field1 = collection.getField(foreignKey);
|
|
const field2 = tcoll.findField((field) => {
|
|
return field.type === 'hasMany' && field.foreignKey === foreignKey;
|
|
});
|
|
if (!field1 && !field2) {
|
|
collection.model.removeAttribute(foreignKey);
|
|
}
|
|
// 删掉 model 的关联字段
|
|
delete collection.model.associations[this.name];
|
|
// @ts-ignore
|
|
collection.model.refreshAttributes();
|
|
// this.collection.removeIndex([this.options.foreignKey]);
|
|
}
|
|
}
|
|
|
|
export interface BelongsToFieldOptions extends BaseRelationFieldOptions, SequelizeBelongsToOptions {
|
|
type: 'belongsTo';
|
|
target?: string;
|
|
}
|