javascript - 如何在express中使用sequelize检索用户帖子?

标签 javascript mysql node.js express sequelize.js

I want to retrieve users post by users logged in Id with following conditions. As currently I am getting user-post as null.

1: If user posted a post. same user should be able to view his post (if same user is not friend with anyone i.e ACCEPTED status).

2: If user posted a post, other users with whom he is friend should be able to view post.

Basically I have used following database design,

1: Users id, first Name, last Name

2: Post id, post

3: UserPost id, postId, (referencing Post table), userId (referencing User table)

4: Friendship id, userId, (referencing User table) friendUserId, (referencing User table) friendshipStatus (e.g values ACCEPTED, REJECTED)

Following is associations and query to retrieve the records schema,

1: User association

const Users = sequelize.define(
    'Users',
    {
      id: {
        type: DataTypes.BIGINT,
        allowNull: false,
        primaryKey: true,
        autoIncrement: true,
        field: 'id'
      },
      firstName: {
        type: DataTypes.STRING(20),
        allowNull: true,
        field: 'firstName'
      },
      lastName: {
        type: DataTypes.STRING(20),
        allowNull: true,
        field: 'lastName'
      },
    {
      tableName: 'users'
    }
  );

Users.associate = models => {
    Users.hasMany(models.Friendships, { foreignKey: 'userId', as: 'friendship'});
    Users.hasMany(models.UserPost, { foreignKey: 'userId', as: 'user-post' 
 }); 
}

2: Friendship association

const Friendships = sequelize.define(
      'Friendships',
      {
        id: {
          type: DataTypes.BIGINT,
          allowNull: false,
          primaryKey: true,
          autoIncrement: true,
          field: 'id'
        },
        userId: {
          type: DataTypes.BIGINT,
          allowNull: false,
          references: {
            model: 'users',
            key: 'id'
          },
          field: 'userId'
        },
        friendUserId: {
          type: DataTypes.BIGINT,
          allowNull: false,
          references: {
            model: 'users',
            key: 'id'
          },
          field: 'friendUserId'
        },
        friendshipStartDate: {
          type: DataTypes.DATE,
          allowNull: true,
          field: 'friendshipStartDate'
        },
        friendshipStatusId: {
          type: DataTypes.STRING(20),
          allowNull: true,
          field: 'friendshipStatusId'
        },
      },
      {
        tableName: 'friendships'
      }
    );

Friendships.associate = models => {
     Friendships.belongsTo(models.UserPost, { foreignKey: 'userId', as: 'user-post' });
     Friendships.belongsTo(models.Users, { foreignKey: 'id', as: 'user' });      
  };

3: Post association

const Post = sequelize.define(
      'Post',
      {
        id: {
          type: DataTypes.INTEGER(11),
          allowNull: false,
          primaryKey: true,
          autoIncrement: true,
          field: 'id'
        },
        post: {
          type: DataTypes.STRING(1000),
          allowNull: false,
        //   defaultValue: '0',
          field: 'Post'
        },
        postStatusId: {
            type: DataTypes.INTEGER(10),
            allowNull: true,
            field: 'PostStatusId'
          },
          createdBy: {
            type: DataTypes.INTEGER(10),
            allowNull: true,
            field: 'CreatedBy'
          },
          updatedBy: {
            type: DataTypes.INTEGER(10),
            allowNull: true,
            field: 'ModifiedBy'
          }
      },
      {
        tableName: 'posts',
        updatedAt: false,
        createdAt: false
      }
    );

Post.associate = models => {
    Post.belongsTo(models.Friendships, { foreignKey:'userId', as: 'friendship' });
    Post.belongsTo(models.UserPost, { foreignKey: 'postId', as: 'userspost' });
    Post.belongsTo(models.Users, { foreignKey: 'id', as: 'user' }); 
};

4: UserPost association

const UserPost = sequelize.define(
      'UserPost',
      {
        id: {
          type: DataTypes.INTEGER(11),
          allowNull: false,
          primaryKey: true,
          autoIncrement: true,
          field: 'id'
        },
        userId: {
          type: DataTypes.STRING(1000),
          allowNull: false,
          references: {
            model: 'user',
            key: 'id' 
          },
          field: 'userId'
        },
        postId: {
            type: DataTypes.INTEGER(10),
            allowNull: true,
            references: {
              model: 'posts',
              key: 'id' 
            },
            field: 'postId'
          }
      },
      {
        tableName: 'user_posts',
        updatedAt: false,
        createdAt: false
      }
    );

UserPost.associate = models => {
     UserPost.hasMany(models.Post, { sourceKey:'postId', foreignKey: 'id', as: 'post' });
     UserPost.hasMany(models.Friendships, { foreignKey:'userId', as: 'friend' 
  }); 
};
序列化查询
const result = await Users.findAll({
     attributes: ['id', 'firstName', 'lastName'],
     subQuery: false,
     include: [
       {
         model: Friendships,
         as: 'friendship',
         attributes: ['userId', 'friendUserId'],
         where: 
             { 
               [Op.or]: {
                 userId: userId,
                 friendUserId: userId
              },
               [Op.and]: {
               friendshipStatusId: 'ACCEPT'
             }
           },
           include: [{
             model: UserPost,
             as: 'user-post',
             attributes: ['userId', 'postId'],
             subQuery: false,
               include: [
               {
                 model: Post,
                 as: 'post',
                 attributes:['id','post'],
               }
             ],
           }]         
       }
     ] })

But in this query I am not getting users post records since there is one entry in database of user post. following is actual result for above query.


响应
[
     {
         "id": 5,
         "firstName": "Abc",
         "lastName": "Xyz",
         "friendship": [
             {
                 "userId": 5,
                 "friendUserId": 6,
                 "user-post": null
             }
         ]
     }
 ]

do anyone having solution for this?

最佳答案

只是为了确保我们在同一页面上,从功能的 Angular 来看,您希望用户能够彼此成为 friend ,并且用户创建的帖子只能由该用户和他的 friend 看到​​。

从 UserPost 的关系 Angular 来看,您希望获得所有有权访问帖子的用户。

如果这是正确的,那么实现它的方法就简单得多。

首先,您不需要用户和帖子(UserPost)之间的多对多关系,因为除非帖子可以有多个创建者,否则您不需要很多用户属于一个帖子。

从原始数据库表的 Angular 来看,我们想要(最小):

用户:

+-----------+-------------+------+-----+---------+----------------+
| Field     | Type        | Null | Key | Default | Extra          |
+-----------+-------------+------+-----+---------+----------------+
| id        | int         | NO   | PRI | NULL    | auto_increment |
| firstName | varchar(20) | YES  |     | NULL    |                |
| lastName  | varchar(20) | YES  |     | NULL    |                |
| createdAt | datetime    | NO   |     | NULL    |                |
| updatedAt | datetime    | NO   |     | NULL    |                |
+-----------+-------------+------+-----+---------+----------------+

友谊:
+-----------+-------------------------------------+------+-----+---------+----------------+
| Field     | Type                                | Null | Key | Default | Extra          |
+-----------+-------------------------------------+------+-----+---------+----------------+
| id        | int                                 | NO   | PRI | NULL    | auto_increment |
| status    | enum('PENDING','ACCEPTED','DENIED') | NO   |     | NULL    |                |
| createdAt | datetime                            | NO   |     | NULL    |                |
| updatedAt | datetime                            | NO   |     | NULL    |                |
| user_1    | int                                 | YES  | MUL | NULL    |                |
| user_2    | int                                 | YES  | MUL | NULL    |                |
+-----------+-------------------------------------+------+-----+---------+----------------+

邮政:
+-----------+--------------------------+------+-----+---------+----------------+
| Field     | Type                     | Null | Key | Default | Extra          |
+-----------+--------------------------+------+-----+---------+----------------+
| id        | int                      | NO   | PRI | NULL    | auto_increment |
| content   | varchar(1000)            | NO   |     | NULL    |                |
| status    | enum('ACTIVE','DELETED') | NO   |     | NULL    |                |
| createdAt | datetime                 | NO   |     | NULL    |                |
| updatedAt | datetime                 | NO   |     | NULL    |                |
| UserId    | int                      | YES  | MUL | NULL    |                |
+-----------+--------------------------+------+-----+---------+----------------+

在 sequelize 中可以通过以下方式完成:
const User = sequelize.define('User',{
        firstName: {
            type: DataTypes.STRING(20),
            allowNull: true,
        },
        lastName: {
            type: DataTypes.STRING(20),
            allowNull: true,
        }
})

User.associate = models => {
    User.hasMany(models.Friendship, { foreignKey: "user_1" });
    User.hasMany(models.Friendship, { foreignKey: "user_2" });
};
const Post = sequelize.define('Post',{
        content: {
            type: DataTypes.STRING(1000),
            allowNull: false,
        },
        status: {
            type: DataTypes.ENUM("ACTIVE", "DELETED"),
            allowNull: false,
            default: "ACTIVE"
        }
    }
);

Post.associate = models => {
    Post.belongsTo(models.User);
};
const Friendship = sequelize.define('Friendship', {
    status: {
        type: DataTypes.ENUM("PENDING", "ACCEPTED", "DENIED"),
        allowNull: false,
        default: "PENDING"
    }
});

用法:
const models = require("./models")
const { Op } = require("sequelize");

const { User, Friendship, Post } = models;

const requestPost = async (user_id,post_id) => {
    let user = await User.findOne({ where: { id: user_id } })
    let post = await Post.findOne({ where: { id: post_id }, include: [User] })
    let isFriend = await Friendship.findOne({
        where: {
            [Op.or]: [
                {
                    user_1: user.id,
                    user_2: post.User.id,
                    status: "ACCEPTED"
                },
                {
                    user_1: post.User.id,
                    user_2: user.id,
                    status: "ACCEPTED"
                }
            ]
        }
    })
    if (isFriend) return post;
}


let run = async () => {
    await models.sequelize.sync({ force: true });
    let user1 = await User.create({
        firstName: "dummy1",
        lastName: "dummy1"
    })
    let user2 = await User.create({
        firstName: "dummy2",
        lastName: "dummy2"
    })
    let user3 = await User.create({
        firstName: "dummy3",
        lastName: "dummy3"
    })
    let user1_user2_friendship_accepted = await Friendship.create({
        user_1: user1.id,
        user_2: user2.id,
        status: "ACCEPTED"
    })
    let user1_user3_friendship_pending = await Friendship.create({
        user_1: user1.id,
        user_2: user3.id,
    })
    let user1_post = await Post.create({
        UserId: user1.id,
        content: "Dummy-content"
    })

    // Example 1:
    // user2 wants to access user1_post:
    let getPost1 = await requestPost(user2.id, user1_post.id) // returns post
    // Example 2:
    // user3 wants to access user1_post:
    let getPost2 = await requestPost(user3.id, user1_post.id) // returns undefined

    console.log("\n\n\n\n")
    if (getPost1) console.log("Returned getPost1")
    if (getPost2) console.log("Returned getPost2")
}

run()

关于javascript - 如何在express中使用sequelize检索用户帖子?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61957086/

相关文章:

javascript - 未调用 NodeJS 函数

node.js - 如何设置 NODE_ENV?

angularjs - SystemJS 插件可以修改已经转译的文件吗?

javascript - 打印二叉树递归函数

javascript - 如何在页面上将小倍数的子组放在一起?

javascript - 为什么 undefined 加 undefined 等于 Javascript 中的 Nan

javascript - 将 LocalStorage 添加到暗模式切换

mysql - 如何在 SQL 中将日期范围转换为整数(整数)

php - 无法仅选择包含数据的列

java - jdbcTemplate 如何执行更新语句并返回变量