sequelize findAll不检查当前用户是否喜欢帖子

时间:2019-10-31 21:39:49

标签: javascript sequelize.js

我有一个场景,如果您喜欢一个帖子,它将改变

liked:falseliked:true

此赞的根据是当前用户是否喜欢该帖子。问题是当新用户注册时,尽管新用户不喜欢该帖子,它仍将显示liked为真。

我如何检查当前用户是否喜欢该帖子?我认为我的逻辑在检查当前用户是否喜欢该帖子方面并不正确。

我想保留findAll功能,我应该获得所有帖子,而不仅仅是当前用户。

Sorta,例如instagram或facebook。

这是帖子数组

enter image description here

这就是我喜欢帖子的方式

顶赞

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;
};

2 个答案:

答案 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帮助,我可以使用序列数据类型VIRTUALgetDataValue来确定当前用户是否喜欢该帖子

更新的代码

帖子(模型)

"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