사용자가 Sequelize를 사용하기 전에 게시물을 좋아했거나 사용하지 않았습니까?

Nov 19 2020

현재 사용자가 게시물을 좋아할 때 해당 like 레코드가 userId 및 postId와 함께 내 Likes 테이블에 추가됩니다.

이제 사용자가 게시물을 볼 때 게시물을 좋아했는지 아닌지 확인하고 싶습니다. 그렇게하려면 게시물 정보를 요청할 때 get 요청에서이를 확인해야 함을 이해합니다.

게시물 정보를 요청할 때 좋아요 테이블에서 현재 사용자의 userId 레코드와 현재 게시물의 postId를 확인해야합니다. 이것이 존재하면 isLiked라는 매개 변수를 반환하고 true로 설정해야합니다. 존재하지 않으면 isLiked = false입니다.

내 Post 모델은 다음과 같습니다.

id: {
  type: Sequelize.INTEGER,
  primaryKey: true,
  autoIncrement: true,
},
title: {
  type: Sequelize.STRING,

},
userId: {
  type: Sequelize.INTEGER,
},
likesCount:{
  type:Sequelize.INTEGER,
  defaultValue:0,
  validate: {
            min: 0,
        }
},

내 좋아요 모델은 다음과 같습니다.

id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER,
 },
 PostId: {
type: Sequelize.INTEGER,
references: {
  model: "Post",
  key: "id",
},
 },
 userId: {
type: Sequelize.INTEGER,
references: {
  model: "User",
  key: "id",
},
 },

내 사용자 모델은 다음과 같습니다.

id: {
  type: Sequelize.INTEGER,
  primaryKey: true,
  autoIncrement: true,
},
name: {
  type: Sequelize.STRING,
 },

내 연결은 다음과 같습니다.

User.hasMany(Post, { foreignKey: "userId" });
Post.belongsTo(User, { foreignKey: "userId" });

Post.hasMany(Likes, { foreignKey: "PostId", targetKey: "id" });
Likes.belongsTo(Post, { foreignKey: "PostId", targetKey: "id" });

User.hasMany(Likes, { foreignKey: "userId", targetKey: "id" });
Likes.belongsTo(User, { foreignKey: "userId", targetKey: "id" });

최신 정보

나는 JWT 미들웨어를 사용하여 사용자 토큰에 서명하기 때문에 계속 조사하고 발견했으며 현재 사용자가 좋아하는 테이블에 레코드가 있는지 확인하고 있습니다. 다음을 시도했지만 누군가 가이 접근 방식이 옳은?

 router.get("/", async (req, res) => {
    const posts = await Post.findAll({
   order: [["createdAt", "DESC"]],
   include: [
  { model: Post_Image, attributes: ["id", "images"] },
  { model: Likes, attributes: ["id", "PostId", "userId"] },
  ],
  });

 if (!posts) return res.status(404).send();

 const baseUrl = config.get("assetsBaseUrl");

 const plainPosts = posts.map((x) => x.get({ plain: true }));
 const resultPosts = [];
  for (const post of plainPosts) {

 let isLiked = false;
 let like = await Likes.findOne({
where: {
[Op.and]: [{ PostId: post.id) }, { userId: 
req.user.id }],

  },
 });

if (like) isLiked = true;

const { Post_Images, ...postAttributes } = post;
const IMAGES = Post_Images.map((postImage) => ({
  url: `${baseUrl}${postImage.images}_full.jpg`,
  thumbnailUrl: `${baseUrl}${postImage.images}_thumb.jpg`,
}));
resultPosts.push({ ...postAttributes, images: IMAGES, isLiked 
});
}

res.send( resultPosts );

 });

답변

1 Anatoly Nov 22 2020 at 10:54

Like다시 한 번 요청할 필요가 없습니다. 모든 게시물의 좋아요를받을 수 있습니다.

for (const post of plainPosts) {
 // check if we have any like among posts' likes that is made by a certain user
 const isLiked = post.Likes.some(x => x.userId === req.user.id);
 const { Post_Images, ...postAttributes } = post;
 ...
doublesharp Nov 19 2020 at 22:42

재정의하려는 경우가 아니면 모든 필드를 지정할 필요가 없습니다. 그렇지 않으면 Sequelize가 대부분의 열을 생성 할 수 있습니다.

const User = sequelize.define(
  'user',
  {
    name: {
      type: Sequelize.STRING,
    },
  },
  { /* options */ }
);

const Post = sequelize.define(
  'post',
  {
    title: {
      type: Sequelize.STRING,
    },
  },
  { /* options */ }
);

// the join table so you can reference it, but doesn't need any columns including primary key (unless you want to a "super join")
const Likes = sequelize.define(
  'likes',
  {}, // no columns here
  { /* options */ }
);

모델 간의 연결을 생성하면 대부분의 foreignKey 필드가 자동으로 생성됩니다. 관계에 through키워드를 사용하여 Likes다 대다로 만드십시오.


// Users can have many Posts
User.hasMany(Post);

// Posts belong to one User
Post.belongsTo(User);

// Users can like more than one Post through the `likes` join table
User.hasMany(Post, { as: 'likes', through: 'likes' });

// Posts can be liked by more than one User through the `likes` join table
Post.hasMany(User, { as: 'likes', through: 'likes' });

조인 테이블을 통해 요약 할 수 있으므로 좋아요 수를 저장할 필요가 없습니다.

// Get the 'likes' count for a Post, instead of saving it on the post
const posts = await Post.findAll({
  attributes: {
    include: [
      [sequelize.fn('COUNT', sequelize.col('likes.userId')), 'likesCount'],
    ],
  },
  include: [
    {
      model: User,
      as: 'likes',
      though: 'likes',
      attributes: [],
      required: false,
    },
  ],
});

// `posts` will be an array of Post instances that have a likesCount property
posts.forEach((post) => {
  console.log(`The post ${post.title} has ${post.likesCount} likes.`);
});

개별 (또는 둘 이상의) 게시물의 경우 게시물을 통해 좋아 한 사용자 목록을 얻을 수 있습니다 (또는 Like모델과 관계 사용).


// Get the user 'likes' for a Post
const post = await Post.findByPk(postId, {
  include: [
    {
      model: User,
      as: 'likes',
      though: 'likes',
      required: false,
    },
  ],
});

post.likes.forEach((like) => {
  console.log(`The user ${like.name} has liked the post ${post.title}.`);
});