اذهب إلى المحتوى

السؤال

نشر

لدي مشروع Pinterest-Clone و واجهتني مشكلة لم استطع حلها والتي عند اضافة تعليق لصورة معينة التعليقات تذهب لجميع مستخدمين وليس لكل مستخدم له تعليق خاص وب تالي صورة avatar و fullname كلها واحد تحديداً في ملف images/[id]/page.tsx 

ارجو مساعدة اريد لكل شخص تعليق خاص له و صور و اسم لكل مستخدم 

pinterest-clone.zip

Recommended Posts

  • 0
نشر

عند إضافة تعليق على صورة معيّنة، كانت جميع التعليقات تظهر بنفس:

الاسم (fullname)

صورة الحساب (avatar)

وذلك بغض النظر عن صاحب التعليق، أي أنّ كل التعليقات كانت تُعرض وكأنها كُتبت من قبل المستخدم الحالي (currentUser).

سبب المشكلة

المشكلة لم تكن في إضافة التعليق نفسها، بل في طريقة جلب وعرض التعليقات:

في جهة الخادم (API)
عند جلب التعليقات من قاعدة البيانات، كان يتم إرجاع بيانات التعليق فقط (مثل النص و userId)، بدون جلب بيانات المستخدم المرتبط بكل تعليق.

في جهة الواجهة (page.tsx)
عند عرض التعليقات، كان يتم استخدام:

currentUser.fullname

currentUser.avatar

لكل تعليق، بدلًا من استخدام بيانات صاحب التعليق الحقيقي.

وبالتالي، جميع التعليقات كانت تُعرض ببيانات المستخدم الحالي فقط.

الحل

1. تعديل API لجلب بيانات المستخدم مع كل تعليق

في ملف route.ts الخاص بالتعليقات، تم تعديل الاستعلام ليشمل بيانات المستخدم باستخدام populate:

const comments = await Comment.find({ imageId }) .populate("userId", "fullname avatar") .sort({ createdAt: -1 });

بهذا الشكل، كل تعليق سيحتوي على:

اسم صاحب التعليق

صورة الحساب الخاصة به

2. تعديل واجهة العرض لاستخدام بيانات صاحب التعليق

في ملف images/[id]/page.tsx، تم تعديل طريقة عرض التعليقات بحيث لا تعتمد على currentUser، وإنما على بيانات المستخدم المرتبطة بكل تعليق:

بدلًا من:

<img src={currentUser.avatar} /> <p>{currentUser.fullname}</p>

تم استخدام:

<img src={c.user?.avatar} /> <p>{c.user?.fullname}</p>

حيث c هو كائن التعليق، و user هو المستخدم الذي تم جلبه عبر populate.

النتيجة

كل تعليق أصبح يُعرض باسم وصورة صاحب التعليق الحقيقي.

لم تعد بيانات المستخدم الحالي تتكرر على جميع التعليقات.

أصبح سلوك النظام مطابقًا للسلوك المتوقع في تطبيق مثل Pinterest.

ملاحظة مهمة

هذه المشكلة تُعد مثالًا واضحًا على أهمية:

فهم العلاقة بين البيانات (Relations)

عدم الخلط بين current user و comment owner

جلب البيانات الصحيحة من الـ API بدل تعويضها في الواجهة

حلّك يدل على فهم جيد للـ Back-end + Front-end data flow، وهو مستوى ممتاز لمشروع عملي.

pinterest-clone_new.rar

  • 0
نشر

المشكلة لديك في ملف app\images\[id]\page.tsx حيث لاحظ أنك تستخدم ال currentUser لعرض التعليقات مما يجعل أن التعليقات الصور وإسم المستخدم تظهر بالمستخدم الحالي وهذا هو سبب المشكلة .

في ملف app\models\Comment.ts يجب أن نقوم بإضافة نموذج user ليتم إعادته مع كل تعليق والذي يحوي إسم الشخص الذي قام بالتعليق وصورة ملفه الشخص وهذا هو كود الملف بعد التعديل :

import mongoose from "mongoose";

interface IComment {
  content: string;
  imageId: mongoose.Schema.Types.ObjectId;
  userId: mongoose.Schema.Types.ObjectId;
}

const commentSchema = new mongoose.Schema<IComment>(
  {
    content: {
      type: String,
      required: true,
    },
    imageId: {
      type: mongoose.Schema.Types.ObjectId,
      required: true,
      ref: "Image",
    },
    userId: {
      type: mongoose.Schema.Types.ObjectId,
      required: true,
      ref: "User",
    },
  },
  { timestamps: true ,toJSON: { virtuals: true }}
);

commentSchema.virtual('user', {
  ref: 'User',
  localField: 'userId', // Field in the current schema
  foreignField: '_id', // Field in the referenced schema
  justOne: true // For a single document reference
});

const Comment =
  mongoose.models.Comment || mongoose.model("Comment", commentSchema);
export default Comment;

الآن في ملف app\api\comments\route.ts سطر 14 يجب أن نعيد النموذج الذي قمنا بتعريفه مع الإستعلام ليكون لدينا المستخدم مع كل تعليق هكذا :

const comments = await Comment.find().populate("user", "fullname avatar").sort({ createdAt: -1 });

الآن في ملف app\images\[id]\page.tsx سطر 182 و 183 و 190 يجب تغير currentUser إلى c.user هكذا :

أولا سطر 182 :

src={c.user?.avatar || "https://res.cloudinary.com/dgagbheuj/image/upload/v1763194734/avatar-default-image_yc4xy4.jpg"}

 ثانيا سطر 183 :

alt={c.user?.fullname || "Anonymous"}

ثالثا سطر190 :

{c.user?.fullname || "Anonymous"}

 

  • 0
نشر

وعليكم السلام ورحمة الله تعالى وبركاته،

المشكلة التي واجهتك تحدث لأن جميع التعليقات تعرض بيانات currentUser بدلا من بيانات المستخدم الذي كتب التعليق فعليا فالحل يتطلب تعديلين أساسيين أولا في جهة ال Backend حيث نستخدم Mongoose populate لجلب بيانات المستخدم مع كل تعليق وثانيا في جهة ال Frontend لعرض البيانات الصحيحة لذا في في ملف app/models/Comment.ts أرجو إضافة virtual property لإنشاء علاقة بين التعليق والمستخدم:

commentSchema.virtual('user', {
  ref: 'User',
  localField: 'userId',
  foreignField: '_id',
  justOne: true
});

هنا تأكد من إضافة toJSON: { virtuals: true } في إعدادات ال Schema حتى يتم إرجاع ال virtuals عند تحويل ال document إلى JSON وفي ملف app/api/comments/route.ts استخدم .populate() لجلب بيانات المستخدم مع التعليقات:

const comments = await Comment.find({ imageId })
  .populate("user", "fullname avatar")
  .sort({ createdAt: -1 });

في ملف app/images/[id]/page.tsx استبدل currentUser ب c.user لعرض بيانات صاحب التعليق الفعلي:

<img src={c.user?.avatar || "default-avatar.jpg"} alt={c.user?.fullname || "Anonymous"} />
<p>{c.user?.fullname || "Anonymous"}</p>

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...