🔺 شرح Laravel

علاقات Eloquent

لماذا العلاقات؟

البيانات الحقيقية مترابطة: مستخدم له مقالات، مقال ينتمي لمستخدم. Eloquent يعبّر عن هذه الروابط بدوال بسيطة.

واحد لمتعدّد (One to Many)

مستخدم له عدّة مقالات:

<?php
class User extends Model
{
    public function posts()
    {
        return $this->hasMany(Post::class);
    }
}

class Post extends Model
{
    public function user()
    {
        return $this->belongsTo(User::class);
    }
}

الاستخدام:

<?php
$user = User::find(1);
foreach ($user->posts as $post) {     // كل مقالات المستخدم
    echo $post->title;
}

$post = Post::find(1);
echo $post->user->name;                // صاحب المقال

واحد لواحد (One to One)

<?php
class User extends Model
{
    public function profile()
    {
        return $this->hasOne(Profile::class);
    }
}

// $user->profile->bio

متعدّد لمتعدّد (Many to Many)

مقال له عدّة وسوم، والوسم في عدّة مقالات (عبر جدول وسيط):

<?php
class Post extends Model
{
    public function tags()
    {
        return $this->belongsToMany(Tag::class);
    }
}

// $post->tags
// $post->tags()->attach($tagId);
// $post->tags()->detach($tagId);

مشكلة N+1 والتحميل المسبق

استدعاء العلاقة داخل حلقة يطلق استعلامًا لكل صفّ (بطيء):

<?php
// ❌ سيّئ: استعلام لكل مقال
$posts = Post::all();
foreach ($posts as $post) {
    echo $post->user->name;   // استعلام منفصل في كل دورة
}

// ✅ جيّد: استعلامان فقط (Eager Loading)
$posts = Post::with('user')->get();
foreach ($posts as $post) {
    echo $post->user->name;
}

💡 with() هي مفتاح الأداء في Laravel — تحمّل العلاقات مسبقًا وتتفادى مشكلة N+1.

أخطاء شائعة

  • إهمال with() فتعاني من مشكلة N+1 وبطء شديد.
  • تسمية دالة العلاقة بصيغة خاطئة (Laravel يستنتج المفاتيح من الاسم).

🎯 التالي: رفع الملفّات.