问题描述
我具有这种结构,旨在通过Sequelize实现多态多对多关联中的渴望加载。
赋予选项 include 时,它返回意外结果(例如不属于此标签的食谱和帖子)
模型
// Food model
Food.belongsToMany(models.Tag,{
through: {
model: "tag_taggable",unique: false,scope: { taggable_type: "food" }
},foreignKey: "taggable_id",constraints: false
});
// Recipe model
Recipe.belongsToMany(models.Tag,scope: { taggable_type: "recipe" }
},constraints: false
});
// Post model
Post.belongsToMany(models.Tag,scope: { taggable_type: "post" }
},constraints: false
});
// Tag model
Tag.belongsToMany(models.Food,unique: false
// scope: { taggable_type: "food" }
},foreignKey: "tag_id",constraints: false
});
Tag.belongsToMany(models.Recipe,unique: false
// scope: { taggable_type: "recipe" }
},constraints: false
});
Tag.belongsToMany(models.Post,unique: false
// scope: { taggable_type: "post" }
},constraints: false
});
Tag.prototype.getTaggables = async function (options) {
const recipes = await this.getRecipe(options);
const foods = await this.getFood(options);
const posts = await this.getPost(options);
return posts.concat(recipes).concat(foods);
}
// Tag_Taggable junction model
const TagTaggable = sequelize.define(
"TagTaggable",{
id: { type: DataTypes.BIGINT,primaryKey: true,autoIncrement: true },tag_id: { type: DataTypes.BIGINT,unique: "tt_unique_constraint" },taggable_id: { type: DataTypes.BIGINT,unique: "tt_unique_constraint",references: null },taggable_type: { type: DataTypes.STRING,}
);
数据库
可标记记录:
+----+--------+-------------+---------------+---------------------------+
| id | tag_id | taggable_id | taggable_type | |
+----+--------+-------------+---------------+---------------------------+
| 1 | 1 | 1 | food | fast,hamburger |
+----+--------+-------------+---------------+---------------------------+
| 2 | 1 | 1 | recipe | fast,Caesar Salad Recipe |
+----+--------+-------------+---------------+---------------------------+
| 3 | 1 | 2 | food | fast,bacon |
+----+--------+-------------+---------------+---------------------------+
| 4 | 2 | 1 | post | fresh,Post 1 |
+----+--------+-------------+---------------+---------------------------+
| 5 | 2 | 2 | recipe | fresh,french Salad Recipe |
+----+--------+-------------+---------------+---------------------------+
| 6 | 2 | 3 | recipe | fresh,Greek Salad Recipe |
+----+--------+-------------+---------------+---------------------------+
查询
查询#1:查找所有标签,包括与其相关联的(食物,帖子,食谱),并加载它们
const tags = await Tag.findAll({
include: [
{ model: db["Food"] /*,required: true*/ },{ model: db["Post"] /*,{ model: db["Recipe"] /*,]
});
return tags[0]; // first tag found
预期:仅出现食物(“汉堡”,“培根”)和食谱(“凯撒沙拉食谱”)。
{ id:1,name:"fast",foods: [ {hamburger},{bacon} ],recipes: [ {caesar salad recipe} ],posts: [] }
[
0: {
id: 1,name: "fast",foods: [
{
name: "hamburger",taggable_id: 1,tag_id: 1
},{
name: "bacon",taggable_id: 2,tag_id: 1
}
],recipes: [
{
name: "Caesar Salad Recipe",{
name: "french Salad Recipe",posts: [
{
name: "Post 1",{
name: "Post 2",tag_id: 1
}
]
}
]
意外的#1
包括相关模型时,范围似乎不影响内部联接(taggable_type看起来像被忽略)。
如果我在tags0上调用getTaggables,我会在数组中获得预期的项目(但是这并不急于加载)
tags[0].getTaggables() // => [ {hamburger},{bacon},{caesar salad recipe} ]
const food = await Food.findOne({
where: { id: 2 },include: [
{
model: db["Tag"] // required: true
}
]
});
预期
{ id:2,name:"bacon",tags:[ {fast} ] }
{
id: 2,name: "bacon",tags: [
{
name: "fast",tag_taggable: {
taggable_id: 2,tag_id: 1
}
},{
name: null
tag_taggable: {
taggable_id: 2,tag_id: 2
}
}
]
意外#2
它在Tag include中包含了错误的模型(其在标签中包含 recipe ),显示为null(某种程度上是其配方)
sql
查询#1 正在生成的错误SQL查询之一: Tag.include(Food,Recipe,Post)
SELECT
`Tag`.`id`,`Tag`.`name`,`Tag`.`color`,`Tag`.`created_at` AS `createdAt`,`Tag`.`updated_at` AS `updatedAt`,`foods`.`id` AS `foods.id`,`foods`.`name` AS `foods.name`,`foods->tag_taggable`.`taggable_id` AS `foods.tag_taggable.taggable_id`,`foods->tag_taggable`.`tag_id` AS `foods.tag_taggable.tag_id`,`recipes`.`name` AS `recipes.name`,`recipes->tag_taggable`.`taggable_id` AS `recipes.tag_taggable.taggable_id`,`recipes->tag_taggable`.`tag_id` AS `recipes.tag_taggable.tag_id`
FROM
`tag` AS `Tag`
LEFT OUTER JOIN `tag_taggable` AS `foods->tag_taggable`
ON `Tag`.`id` = `foods->tag_taggable`.`tag_id`
LEFT OUTER JOIN `food` AS `foods`
ON `foods`.`id` = `foods->tag_taggable`.`taggable_id`
LEFT OUTER JOIN `tag_taggable` AS `recipes->tag_taggable`
ON `Tag`.`id` = `recipes->tag_taggable`.`tag_id`
LEFT OUTER JOIN `recipe` AS `recipes`
ON `recipes`.`id` = `recipes->tag_taggable`.`taggable_id`;
LEFT OUTER JOIN `tag_taggable` AS `post->tag_taggable`
ON `Tag`.`id` = `posts->tag_taggable`.`tag_id`
LEFT OUTER JOIN `post` AS `posts`
ON `posts`.`id` = `posts->tag_taggable`.`taggable_id`;
查询#2 生成的第二个错误的SQL查询: Food.include(Tag)
SELECT
`Food`.`id`,`Food`.`name`,`tags`.`id` AS `tags.id`,`tags`.`name` AS `tags.name`,`tags->tag_taggable`.`taggable_id` AS `tags.tag_taggable.taggable_id`,`tags->tag_taggable`.`tag_id` AS `tags.tag_taggable.tag_id`
FROM
`food` AS `Food`
LEFT OUTER JOIN `tag_taggable` AS `tags->tag_taggable`
ON `Food`.`id` = `tags->tag_taggable`.`taggable_id`
LEFT OUTER JOIN `tag` AS `tags`
ON `tags`.`id` = `tags->tag_taggable`.`tag_id`
AND `tags->tag_taggable`.`taggable_type` = 'food' WHERE `Food`.`id` = 2;
包裹
"sequelize": "^6.3.4","sequelize-cli": "^6.2.0","sqlite3": "^5.0.0",
我如何处理这个模型,包括急切的装载情况?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)