问题描述
现在,我先插入产品,然后在数组中插入多个产品标签。
但是产品标签将是重复的,而不会验证标签是否存在。
这是我使用的代码:
let product = {
product: {
name: 'techtech',tagline: '描述',thumbnail: 'images/products/techtech/thumbnail.png'
},tags: [
{ name: 'Android',slug: 'android' },{ name: 'MacOS',slug: 'macos' },{ name: 'Windows',slug: 'windows' },{ name: 'Linux',slug: 'linux' }
],links: [ { url: 'techtech.cc' } ],covers: [
{ url: 'images/products/techtech/cover_0.png',index: 0 },{ url: 'images/products/techtech/cover_1.png',index: 1 }
]
}
// insert product
return db.transaction(trx => {
return trx('products')
.insert(product.product)
.returning('id')
// insert product_tags
.then(productIDs => {
return trx(productTags)
.insert(product.tags)
.returning('id')
// insert product_producttag_mapping
.then(productTagIDs => {
let productTags = productTagIDs.map((productTagID) => {
let productTag = {
product_id: productID,producttag_id: productTagID
}
return productTag;
});
return trx('product_producttag_mapping')
.insert(productTags)
.returning('id')
})
})
解决方法
请注意,插入产品时,变量为productIDs
,但是您正在使用productTag
创建productId
。您可能要添加const productId = productIds[0]
。
创建productTag时,还需要使用.id
,如下所示。因为knex会返回具有该属性的对象。
let productTag = {
product_id: productID.id,producttag_id: productTagID.id
}
但是您的实际问题是:如何使标签名称唯一?这会在插入时给您一个不错的错误。没有事务,您可以忽略该错误。 Postgres和Mysql具有不错的功能ON CONFLICT DO NOTHING
。我不确定数据库在检测到重复项时是否会返回现有ID。因此,我认为您不会无所事事地阅读现有标签。通过他们的名字找到他们。在该列上有一个索引,应该是合理的快速。
专业提示:使用async/await
重写代码时,小错误变得更加明显,您可以避免回调地狱。您不太可能会避免额外的查询。