Sequelize: использование include для объединенной таблицы - PullRequest
0 голосов
/ 11 февраля 2019

У меня есть 4 модели: User, Skill, SkillToLearn и SkillToTeach.SkillToLearn и SkillToTeach содержат два столбца userId и skillId для отслеживания навыка (заданного skillId), который пользователь (заданный userId) хочет изучить или обучить.

MyЦель состоит в том, чтобы использовать заявление include, которое дает Sequelize, таким образом, чтобы я мог возвращать данные всех пользователей, включая список навыков, которые они изучают, и список навыков, которым они учат.Мне нужен ответ, подобный следующему:

[
    {
        "id": 1,
        "username": "janedoe",
        "skillsLearning": [
            {
                "skillId": 1,
                "name": "arts"
            }
        ],
        "skillsTeaching": [
            {
                "skillId": 2,
                "name": "cooking"
            }
        ]
    }
]

Однако вместо этого я получаю следующий ответ:

[
    {
        "id": 1,
        "username": "janedoe",
        "skillsLearning": [
            {
                "skillId": 1,
                "Skill": {
                    "name": "arts"
                }
            }
        ],
        "skillsTeaching": [
            {
                "skillId": 2,
                "Skill": {
                    "name": "cooking"
                }
            }
        ]
    }
]

Я попытался включить Skill вместо SkillToLearn и SkillToTeach, но я получил сообщение о том, что Skill не связан с User.Я не уверен, что мои схемы и ассоциации неверны.

User.js

    const User = sequelize.define("User", {
        username: {
            type: DataTypes.STRING,
            allowNull: false,
            unique: true
        },
        email: {
            type: DataTypes.STRING,
            allowNull: false,
            unique: true,
            validate: {
                isEmail: true
            }
        },
        password: {
            type: DataTypes.STRING,
            allowNull: false
        },
        description: {
            type: DataTypes.TEXT
        }
    }, {
        freezeTableName: true
    });

    User.associate = function (models) {
        User.hasMany(models.SkillToLearn, {
            as: "skillsLearning",
            onDelete: "cascade",
            foreignKey: "userId",
            sourceKey: "id"
        });

        User.hasMany(models.SkillToTeach, {
            as: "skillsTeaching",
            onDelete: "cascade",
            foreignKey: "userId",
            sourceKey: "id"
        });
    };

Skill.js

const Skill = sequelize.define("Skill", {
        name: {
            type: DataTypes.STRING,
            allowNull: false,
            unique: true
        }
    }, {
        freezeTableName: true
    });

    Skill.associate = function (models) {
        Skill.hasMany(models.SkillToLearn, {
            as: "usersLearning",
            onDelete: "cascade",
            foreignKey: "skillId",
            sourceKey: "id"
        });

        Skill.hasMany(models.SkillToTeach, {
            as: "usersTeaching",
            onDelete: "cascade",
            foreignKey: "skillId",
            sourceKey: "id"
        });
    };

SkillToLearn.js

const SkillToLearn = sequelize.define("SkillToLearn", {
        userId: {
            type: DataTypes.INTEGER,
            allowNull: false,
            primaryKey: true
        },
        skillId: {
            type: DataTypes.INTEGER,
            allowNull: false,
            primaryKey: true
        }
    }, {
        freezeTableName: true
    });

    SkillToLearn.associate = function (models) {
        SkillToLearn.belongsTo(models.User, {
            foreignKey: "userId",
            targetKey: "id"
        });

        SkillToLearn.belongsTo(models.Skill, {
            foreignKey: "skillId",
            targetKey: "id"
        });
    };

SkillToTeach.js

const SkillToTeach = sequelize.define("SkillToTeach", {
        userId: {
            type: DataTypes.INTEGER,
            allowNull: false,
            primaryKey: true
        },
        skillId: {
            type: DataTypes.INTEGER,
            allowNull: false,
            primaryKey: true
        }
    }, {
        freezeTableName: true
    });

    SkillToTeach.associate = function (models) {
        SkillToTeach.belongsTo(models.User, {
            foreignKey: "userId",
            targetKey: "id"
        });

        SkillToTeach.belongsTo(models.Skill, {
            foreignKey: "skillId",
            targetKey: "id"
        });
    };

dataRoutes.js

db.User
        .findAll({
            attributes: ["id", "username"],
            include: [
                {
                    model: db.SkillToLearn,
                    as: "skillsLearning",
                    attributes: ["skillId"],
                    include: [
                        {
                            model: db.Skill,
                            attributes: ["name"]
                        }
                    ]
                },
                {
                    model: db.SkillToTeach,
                    as: "skillsTeaching",
                    attributes: ["skillId"],
                    include: [
                        {
                            model: db.Skill,
                            attributes: ["name"]
                        }
                    ]
                }
            ]
        })
        .then(results => res.json(results));
});

Могу ли я получить имя навыка, не имея его в объекте?Должен ли я просто сделать несколько запросов и построить ответ, используя мой собственный литерал объекта?Спасибо!

...