我有一个场景,如果您喜欢一个帖子,它将改变
liked:false
至liked:true
此赞的根据是当前用户是否喜欢该帖子。问题是当新用户注册时,尽管新用户不喜欢该帖子,它仍将显示liked
为真。
我如何检查当前用户是否喜欢该帖子?我认为我的逻辑在检查当前用户是否喜欢该帖子方面并不正确。
我想保留findAll
功能,我应该获得所有帖子,而不仅仅是当前用户。
Sorta,例如instagram或facebook。
这是帖子数组
这就是我喜欢帖子的方式
顶赞
likePost: async (req: any, res: Response) => {
const created = await models.Likes.findOne({
where: {
userId: req.session.user.id,
resourceId: req.params.id
}
});
console.log(created);
const post = await models.Post.findOne({ where: { id: req.params.id } });
// if like not created then do this
if (!created && post) {
await models.Likes.create({
userId: req.session.user.id,
resourceId: req.params.id
}).then(() => {
post.increment("likeCounts", { by: 1 });
post.update({ liked: req.session.user.id ? true : false });
res.status(200).send({
message: "You liked this post"
});
});
// else if post does not exist
} else if (!post) {
res.status(200).send({
message: "there is not post to be liked"
});
} else {
// else if a like does exist destroy like
await models.Likes.destroy({
where: {
userId: req.session.user.id
}
}).then(() => {
post.decrement("likeCounts", { by: 1 });
res.status(200).send({
message: "You unliked this post"
});
});
}
这是我获取帖子的方式。
获取帖子
getPosts: async (req: any, res: Response) => {
await models.Post.findAll({
include: [
{ model: models.User, as: "author", attributes: ["username"] },
{ model: models.Likes }
],
order: [["createdAt", "DESC"]],
limit: 6
}).then(posts => {
res.json(posts);
});
},
Post.js(模型)
"use strict";
module.exports = (sequelize, DataTypes) => {
var Post = sequelize.define("Post", {
title: DataTypes.STRING,
postContent: DataTypes.STRING,
liked: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: false
},
likeCounts: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: 0,
validate: {
min: 0,
}
},
authorId: DataTypes.INTEGER
}, {});
Post.associate = function (models) {
Post.belongsTo(models.User, {
as: "author",
foreignKey: "authorId",
onDelete: "CASCADE"
});
Post.hasMany(models.Likes, {
foreignKey: "resourceId",
timestamps: false,
targetKey: "id",
onDelete: "CASCADE"
});
};
return Post;
};
答案 0 :(得分:2)
我相信您看到的错误是因为您没有解决由以下人员返回的承诺:
post.increment("likeCounts", { by: 1 });
post.update({ liked: req.session.user.id ? true : false });
这意味着将在执行这些查询之前发送响应。会话中的任何时间post.liked
都将被设置为true。如果稍后的查询失败,则您可能要考虑使用事务回滚某些先前的查询。我还建议使用user.id
进行并发查询(这样会更快),并单独使用Promise.all()
而不混入async/await
。
thenables
仅在getPost()上为当前用户返回likePost: async (req: any, res: Response) => {
// fetch created and post at the same time
const [ created, post ] = await Promise.all([
models.Likes.findOne({
where: {
userId: req.session.user.id,
resourceId: req.params.id
}
}),
models.Post.findOne({
where: {
id: req.params.id
}
}),
]);
// no post, no updates
if (!post) {
return res.status(200).send({
message: "there is no post to be liked"
});
}
// we are going to make updates, so use a transaction, you will need to reference sequelize
let transaction;
try {
transaction = await sequelize.transaction();
if (!created && post) {
// use Promise.all() for concurrency
await Promise.all([
models.Likes.create({
userId: req.session.user.id,
resourceId: req.params.id
}, { transaction }),
post.increment("likeCounts", { by: 1, transaction }),
post.update({ liked: req.session.user.id ? true : false }, { transaction }),
]);
await transaction.commit();
return res.status(200).send({
message: "You liked this post"
});
}
await Promise.all([
models.Likes.destroy({
where: {
userId: req.session.user.id
}
}, { transaction }),
post.decrement("likeCounts", { by: 1, transaction }),
]);
await transaction.commit();
return res.status(200).send({
message: "You unliked this post"
});
} catch (err) {
if (transaction) {
await transaction.rollback();
}
console.log('There was an error', err);
return res.status(500);
}
}
Likes
答案 1 :(得分:1)
因此,通过使用@doublesharp帮助,我可以使用序列数据类型VIRTUAL和getDataValue来确定当前用户是否喜欢该帖子
更新的代码
帖子(模型)
"use strict";
module.exports = (sequelize, DataTypes) => {
var Post = sequelize.define("Post", {
title: DataTypes.STRING,
postContent: DataTypes.STRING,
liked: {
type: DataTypes.VIRTUAL,
allowNull: false,
defaultValue: false,
get: function () {
return this.getDataValue('Likes').length ? true : false;
}
},
likeCounts: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: 0,
validate: {
min: 0,
}
},
authorId: DataTypes.INTEGER
}, {});
Post.associate = function (models) {
Post.belongsTo(models.User, {
as: "author",
foreignKey: "authorId",
onDelete: "CASCADE"
});
Post.hasMany(models.Likes, {
foreignKey: "resourceId",
timestamps: false,
targetKey: "id",
onDelete: "CASCADE"
});
};
return Post;
};
//# sourceMappingURL=post.js.map