【发布时间】:2020-12-07 13:02:29
【问题描述】:
我有两个表 'temp_users' 和 'ratings'
TABLE 1 (temp_users)
temp_user_id(pkey) | ip_address | total_ratings
-----------------------------------------
| |
| |
| |
TABLE 2 (ratings)
rating_id | rating | product_id | temp_user_id(fkey)
----------------------------------------------------
| | |
| | |
| | |
我正在尝试这样做,以便一旦用户尝试对产品进行评分,就会使用他们的 IP 地址创建一个 temp_user。
一旦将 ip_address 插入表中,就会生成 user_temp_id,除非该 ip 地址已存在于表中(我正在使用 postgres ON CONFLICT 来完成此操作,如下面的代码所示)。
一旦 temp_user 对产品进行评分,他们就无法再次对其进行评分。换句话说,一个 temp_user 只能对同一个产品进行一次评分。
当我使用 'ON CONFLICT' 或 'WHERE NOT EXIST' 子句时,我完成此操作的代码不起作用,当我允许插入相同 IP 地址的重复项时工作正常。我的代码如下:
app.post("/rating", (req, res) => {
const ip = // <==== this is just to get the ip address. works fine.
(req.headers["x-forwarded-for"] || "").split(",").pop().trim() ||
req.connection.remoteAddress ||
req.socket.remoteAddress ||
req.connection.socket.remoteAddress;
const { rating, product_id } = req.body;
knex
.raw( // <=== inserts ip and temp_user_id. returns temp_user_id
`INSERT INTO temp_users(ip_address)
VALUES ('${ip}')
ON CONFLICT (ip_address)
DO UPDATE SET total_ratings = EXCLUDED.total_ratings
RETURNING temp_user_id`
)
.then((results) => { // <=== counts the ratings to check later if user rated before
return knex("ratings")
.count("*")
.as("total")
.where({
product_id: product_id,
temp_user_id: results[0].temp_user_id,
})
.then((data) => { // <=== check if user rated before, if not insert new user
if (data[0].count > 0) {
return res.status(400).json("user already rated");
} else {
return knex("ratings")
.returning("*")
.insert({
rating: rating,
product_id: product_id,
temp_user_id: results[0].temp_user_id,
})
.then((response) => res.json(response))
.catch((err) => err);
}
});
})
.then((response) => res.json(response))
.catch((err) => err);
});
如果我在下面使用此代码,代码可以完美运行,但它会插入多个具有不同 temp_user_ids 的 IP 地址,这不是我想要的。
所以通过切换这部分代码...
knex
.raw(
`INSERT INTO temp_users(ip_address)
VALUES ('::5')
ON CONFLICT (ip_address)
DO UPDATE SET total_ratings = EXCLUDED.total_ratings
RETURNING temp_user_id`
)
到这里……
knex("temp_users")
.insert({
ip_address: ip,
})
.returning("*")
我在链接承诺方面做错了什么?我怎样才能让它工作? 任何帮助将不胜感激。
【问题讨论】:
-
你有一个内部和一个外部
.then(response => res.json(response))。如果一切都成功,两者都将(尝试)执行,外部的对内部的res.json(response)返回的任何内容进行操作。 -
请注意
.catch(err => err)将err发送到成功路径。要么不接,要么接再扔。
标签: postgresql express promise knex.js