Sequelize不存储其他连接表字段

时间:2017-03-10 12:31:34

标签: node.js postgresql typescript sequelize.js

我有两个具有多对多关联的模型。我已经为连接表创建了一个额外的模型,因此我可以使用连接表存储数据。

现在关联工作正常,但应该存储在连接表中的数据不会持久保存到数据库中。

我为每个模型都有一个单独的类,它将续集的api抽象出来。

通过调试,我注意到sequelize模型的dataValues设置正确,但sequelize只运行Select查询而不是更新查询。 我想Select查询是检查数据是否已经插入,因为相关模型不是从数据库中提取的,而是从http帖子体构建的。

也许这是因为我的模型而发生,但我不确定错误在哪里。 有什么想法吗?

DAO 1

export const ProjectModel: Sequelize.Model<IProjectInstance, IProjectModel> = db.define<IProjectInstance, IProjectModel>('project', {
    privateTitle: {
        type: Sequelize.STRING,
        allowNull: false,
        validate: {
            notEmpty: true
        }
    },
    publicTitle: {
        type: Sequelize.STRING,
        allowNull: true
    }
}, {
    defaultScope: {
        include: [
            {
                model: ProfileModel,
                as: 'coworkers',
                include: [
                    {
                        model: UserModel,
                        as: 'user'
                    }
                ]
            }
        ]
    }
});


ProjectModel.belongsToMany(ProfileModel, {
    as: 'coworkers',
    through: ProjectProfileModel,
    foreignKey: 'projectId',
    otherKey: 'profileId'
});

DAO 2

export const ProfileModel: Sequelize.Model<IProfileInstance, IProfileModel> = db.define<IProfileInstance, IProfileModel>('profile', {
    label: {
        type: Sequelize.STRING
    },
    userId: {
        allowNull: false,
        type: Sequelize.INTEGER,
        references: {
            model: UserModel,
            key: 'id'
        }
    }
}, {
    scopes: {
        user: {
            include: [
                {
                    model: UserModel,
                    as: 'user'
                }
            ]
        }
    }
});

加入DAO

export const ProjectProfileModel: Sequelize.Model<IProjectProfileInstance, IProjectProfileModel> = db.define<IProjectProfileInstance, IProjectProfileModel>('projectProfile', {
    start: {
        type: Sequelize.DATE,
        allowNull: false,
        defaultValue: Sequelize.NOW
    },
    end: {
        type: Sequelize.DATE,
        allowNull: true
    },
    role: {
        type: Sequelize.STRING,
        allowNull: true
    }
});

模型1

export class Project implements IModel {
    private _model: IProjectInstance;
    private _coworkers: Coworker[];

    public static async get(number: number, scope?: string): Promise<Project> {
        const Model = scope ? ProjectModel.scope(scope) : ProjectModel;
        return Model
            .findOne({
                where: {
                    number: number
                }
            })
            .then(project => new Project(project));
    }

    public static assignable: string[] = ['id', 'coworkers'];

    constructor(data: (IProjectInstance | IProjectObject), instance?: IProjectInstance) {
        if (isInstance(data)) {
            this._model = data;
            this._customer = data.customer ? new Customer(data.customer) : undefined;
        }else if (instance) {
            this._model = instance;
        }else {
            this._model = ProjectModel.build();
        }
        if (!isInstance(data)) {
            assign(this, data, Project.assignable);
        }
    }

    public get coworkers(): Coworker[] {
        if (this._coworkers === undefined) {
            this._coworkers = map(this._model.coworkers,
                coworker => new Coworker(coworker, this.id));
        }
        return this._coworkers;
    }

    public set coworkers(value: Coworker[]) {
        this._coworkers = map(value, profile => profile instanceof Coworker ? profile : new Coworker(profile, this.id));
    }

    public async save(): Promise<Project> {
        await db.transaction(async (transaction) => {
            await this._model.setCoworkers(map(this._coworkers, (coworker: Coworker) => coworker.model), { transaction });
            await this._model.save({ transaction });
        });
        return this;
    }

    public async delete(): Promise<void> {
        return this._model.destroy();
    }
}

模型2

export class Profile implements IModel {
    private _model: IProfileInstance;

    constructor(data: (IProfileInstance | IProfileObject )) {
        if (isInstance(data)) {
            this._model = data;
        }else {
            this._model = ProfileModel.build();
            assign(this, data, ['id', 'label', 'user', 'userId']);
        }
    }


    public async save(): Promise<Profile> {
        await this._model.save();
        return this;
    }

    public async delete(): Promise<void> {
        return this._model.destroy();
    }
}

关联模式

export class Coworker extends Profile {

    constructor(data, project) {
        super(data);
        if (!isInstance(data)) {
            this.model.projectProfile = ProjectProfileModel.build();
            this.projectId = project;
            assign(this, data);
        }
    }

    public get id(): number {
        return this.model.id;
    }

    public set id(value: number) {
        this.model.id = value;
        if (this.model.projectProfile !== undefined) {
            this.model.projectProfile.profileId = value;
        }
    }

    public get profileId(): number {
        return this.model.projectProfile.profileId;
    }

    public set profileId(value: number) {
        this.model.projectProfile.profileId = value;
    }

    public get projectId(): number {
        return this.model.projectProfile.projectId;
    }

    public set projectId(value: number) {
        this.model.projectProfile.projectId = value;
    }

    public get start(): Date {
        return this.model.projectProfile.start;
    }

    public set start(value: Date) {
        this.model.projectProfile.start = value;
    }

    public get end(): Date {
        return this.model.projectProfile.end;
    }

    public set end(value: Date) {
        this.model.projectProfile.end = value;
    }

    public get role(): string {
        return this.model.projectProfile.role;
    }

    public set role(value: string) {
        this.model.projectProfile.role = value;
    }
}

控制器

function update(req, res, next) {
    Project.get(req.param.id)
        .then(project => assign(project, req.body))
        .then(project => project.save())
        .then(project => {
            res.json(project);
            res.status(200);
            res.end();
        })
        .catch(err => next(err));
}

1 个答案:

答案 0 :(得分:0)

好的,修复非常简单。模型上的关联属性必须是对象而不是Sequelize Instance。 下面的关联模型包含固定的构造函数。

export class Coworker extends Profile {

    constructor(data, project) {
        super(data);
        if (!isInstance(data)) {
            this.model.projectProfile = {};
            this.projectId = project;
            assign(this, data);
        }
    }

    public get id(): number {
        return this.model.id;
    }

    public set id(value: number) {
        this.model.id = value;
        if (this.model.projectProfile !== undefined) {
            this.model.projectProfile.profileId = value;
        }
    }

    public get profileId(): number {
        return this.model.projectProfile.profileId;
    }

    public set profileId(value: number) {
        this.model.projectProfile.profileId = value;
    }

    public get projectId(): number {
        return this.model.projectProfile.projectId;
    }

    public set projectId(value: number) {
        this.model.projectProfile.projectId = value;
    }

    public get start(): Date {
        return this.model.projectProfile.start;
    }

    public set start(value: Date) {
        this.model.projectProfile.start = value;
    }

    public get end(): Date {
        return this.model.projectProfile.end;
    }

    public set end(value: Date) {
        this.model.projectProfile.end = value;
    }

    public get role(): string {
        return this.model.projectProfile.role;
    }

    public set role(value: string) {
        this.model.projectProfile.role = value;
    }
}