【问题标题】:How to set extra attributes of through model on creation in SequelizeJS?如何在 SequelizeJS 中设置创建时通过模型的额外属性?
【发布时间】:2018-10-12 17:33:00
【问题描述】:

我的模型:

 Recipe (id, name)
 Ingredient (id, name)
 Recipe_Ingredient (recipeId, ingredientId, quantity)

我的联想:

Recipe.belongsToMany(Ingredient, { through: Recipe_Ingredient })
Ingredient.belongsToMany(Recipe, { through: Recipe_Ingredient })

我的问题:

我如何创建一个包含一些成分及其数量的食谱?

我试过了:

Recipe.create({
  name: 'Pizza',
  ingredients:[
    {
      name: 'mozarella',
      recipe_ingredients: {
          quantity: 5
      }
    }
  ]
}, {
    include:[Ingredient]
})

为配方、成分和配方_成分创建记录。唯一的问题是数量的值不是从数据源收集的。

【问题讨论】:

  • 如果在创建中指定through 会怎样? include:[ { model: Ingredient, through: Recipe_Ingredient } ].
  • 可能还想尝试receipe_ingredient(不是复数),因为它不是数组...
  • @doublesharp 不起作用,表名也被冻结,所以复数没有问题
  • 我相信你需要更新你的include:{ include: [{ association: Ingredient, include: [ Recipe_Ingredient ] }] }
  • @mcranston18 我试过了,但它并没有真正起作用。你有一个可行的例子吗?

标签: javascript sequelize.js


【解决方案1】:

过去无法做到这一点,但在 2018 年 10 月 23 日,这已在 sequelize PR #10050 中得到修复。

截至今天(2018 年 10 月 24 日),该修复程序尚未发布,但只要 v5.0.0-beta14 发布,您就可以执行以下操作:

Recipe.create({
    name: 'Pizza',
    ingredients: [
        {
            name: 'mozarella',
            recipe_ingredient: {
                quantity: 5
            }
        }
    ]
}, {
    include: Ingredient
})

另外,请注意,正确的用法是 recipe_ingredient: 的单数形式,而不是您在问题中尝试的复数形式。这是有道理的,因为对于与给定食谱相关联的给定成分,始终只涉及一个 Recipe_Ingredient。

如果你不想等待v5.0.0-beta14(虽然它可能很快就会发布),你可以直接从github的master分支安装它,如下所示:

npm install --save https://github.com/sequelize/sequelize/tarball/master

【讨论】:

    【解决方案2】:

    我找到了一个解决方案,灵感来自 pedro here (How do I ORM additional columns on a join table in sequelize?) 的答案,并且是通过改变视角给出的。

    receipe (name:string)
    ingredient (quantity:int)
    type (name: string)
    
    receipe.hasMany(ingredient, {as:'ingredients'} )
    ingredient.belongsTo(type)
    

    然后我可以像这样使用数据:

    receipe.create({
      name: 'Pizza',
      ingredients:[
        {
          quantity: 5,
          type: {
             name: 'ingredient 1'
          }
        }, {
          quantity: 6,
          type: {
             name: 'ingredient 2'
          }
        } {
          quantity: 5,
          type_id: 1
        }]
    }, {
        include:[{
           model; ingredient,
           as: 'ingredients',
           include:[{
             model: type
           }]
        }]
    })
    

    它有一些缺点,但对我来说已经足够了。

    一个问题可能是如果你添加两个相同的新类型的项目,你会得到一个唯一的键冲突(因为类型是唯一的,如果类型之前存在,sequelize 将不会尝试搜索尝试创建它)。

    另一个问题是,如果你只在数据中指定type_id,它实际上并不会返回结果中那个引用的类型。

    【讨论】:

    • 您好!很好的解决方案。我喜欢你在这里所做的视角改变。但我也同意你的观点,如果它以你最初想象的方式工作会更好。顺便说一句,在调查其他解决方案时,我测试了一些东西,并在我的一次尝试中偶然发现了一条奇怪的错误消息,并打开了一个关于它的问题:#10034。让我们看看:)
    • 顺便说一句,在您的问题中,您尝试了receipe_ingredients: { quantity: 5 },但对我来说receipe_ingredient: { quantity: 5 }(单数)更有意义(尽管它们都不起作用)。
    • 嘿@PedroA!谢谢,看看有没有解决办法! :)
    猜你喜欢
    • 1970-01-01
    • 2010-09-29
    • 1970-01-01
    • 2016-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多