2017-03-10 32 views
0

我有兩個模型與多對多關聯。我爲連接表創建了一個附加模型,所以我可以使用連接表存儲數據。續集不存儲其他加入表字段

現在,關聯工作正常,但應該存儲在連接表中的數據不會持久保存到數據庫。

我有一個單獨的類爲每個模型提取sequelize api。

通過調試,我注意到sequelize模型的dataValues設置正確,但sequelize只運行Select查詢而不是更新查詢。 我猜Select查詢是檢查數據是否已經被插入,因爲關聯的模型不是從數據庫中獲取,而是從http post主體構建。

也許這是因爲我的模型,但我不知道錯誤在哪裏。 任何想法的?

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)); 
} 

回答

0

好的,修復很簡單。模型上的關聯屬性必須是一個對象而不是一個Sequelize實例。 下面的關聯模型包含固定構造函數。

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; 
    } 
}