Sequelize Association:可以使用多表相同的字段吗?

时间:2017-03-02 04:11:37

标签: node.js sequelize.js

我有以下四种模式

用户

user_id
user_email

许可证

permit_id
permit_name

标签

label_id
label_name
module_name   (user or permit)

ModuleLabel

module_label_id  
label_id   **(fk - Label table)**
module_id  (user_id or permit_id)

如何使用sequelize获取许可数据时获取映射标签详细信息?

从"中选择"允许,加入ModuleLabel,其中module_id = permit_id&& module_name =' permit'(来自Label表),然后从那里加入Label

2 个答案:

答案 0 :(得分:0)

根据您的描述,您似乎正在尝试从"中选择" Permit,加入ModuleLabel module_id=permit_id,然后从那里加入Label。如果这不正确,请澄清问题。

如果是这种情况,那么通过设置hasMany关系绝对可以做到。但是,我建议不要像这样以通用方式重用关键字段(其中module_id可以是许可证或用户ID)。我个人花了很多时间在Drupal中使用原始Entity表,它们执行相同的操作 - ID可以映射到任意数量的外表,并且您必须评估每个记录的类型才能知道哪一个加入。它造成了非常混乱和大的查询,并且如果某些内容被破坏,就会匆忙调试。 (而且很容易出错。)

答案 1 :(得分:0)

它可以完成,但绝对没有数据库中的约束。在您的情况下,module_id中的ModuleLabel字段可能会引用userpermit表。我可以向您展示一些实现草图,但我会建议重建模式,例如创建UserLabelPermitLabel模型,这些模型对UserPermit具有外键约束。但是,以下是您可以按照自己的方式进行的方式

// in User model definition
classMethods: {
    associate: function(models){
        this.hasMany(models.ModuleLabel, { foreignKey: 'module_id', constraints: false });
    }
}

// in Permit model definition
classMethods: {
    associate: function(models){
        this.hasMany(models.ModuleLabel, { foreignKey: 'module_id', constraints: false });
    }
}

以上关联允许我们在查询ModuleLabelUser时加入Permit模型。最重要的部分是记住阻止创建数据库约束的constraints: false。让我们继续吧。 Label模型不需要任何关联,只需要字段声明。最后一个模型是ModuleLabel

// in ModuleLabel model definition
classMethods: {
    associate: function(models){
        this.belongsTo(models.Label, { foreignKey: 'label_id' });
        this.belongsTo(models.User, { foreignKey: 'module_id', constraints: false });
        this.belongsTo(models.Permit, { foreignKey: 'module_id', constraints: false });
    }
}

现在,为了执行您想要的查询,您可以执行此操作

models.Permit.findAll({
    include: [
        {
            model: models.ModuleLabel,
            include: [
                {
                    model: models.Label,
                    where: { module_name: 'permit' }
                }
            ]
        }
    ]
}).then((result) => {
    console.log(result);
});

上面的查询将生成类似于下面提到的SQL

SELECT * FROM Permits
LEFT OUTER JOIN ModuleLabels
ON Permits.id = ModuleLabels.module_id
INNER JOIN Labels
ON ModuleLabels.label_id = Labels.id
AND Label.module_name = 'permit';