لارافيل, Model / 2024-05-14

الدوال latestOfMany - oldestOfMany - ofMany في لارافيل

الدوال latestOfMany - oldestOfMany - ofMany في لارافيل

2024-05-14 وقت القراءه : 2 دقائق

ربما لا يخلو أي مشروع من علاقة one-to-may بين الـ models، حيث يمكن جلب جميع السجلات لـ model معين، لكن ببعض الأحيان قد يتطلب الأمر جلب سجل معين من العلاقة وليس جميع السجلات.

مثال : لفرض أن لدينا User Model و Post Model، وكل User له مجموعة من Post ، ونريد جلب فقط أخر Post تمت إضافته من قبل هذا الـ User.

جدول posts

Schema::create('posts', function (Blueprint $table) {
    $table->id();
    $table->string('title');
    $table->integer('views');
    $table->foreignId('user_id')->constrained();
    $table->timestamps();
});

بالطبع يمكن عمل ذلك من خلال جملة eloquent

public function posts(): HasMany
{
    return $this->hasMany(Post::class);
}


$users=User::with(['posts'=>function ($query) {
    $query->orderBy('id', 'DESC')->first();
}])->first();
return $users;

إلا إنه عوضا عن جملة eloquent بالأعلى يمكن القيام بذلك من خلال الـ model من خلال إستخدام latestOfMany



الدالة latestOfMany في لارافيل

بداية نذهب إلى User Model وننشئ علاقة جديده لتكن مثلا بإسم lastPost، ونغير نوع العلاقة من hasMany إلى hasOne ومن ثم نمرر latestOfMany

public function lastPost()
{
    return $this->hasOne(Post::class)->latestOfMany();
}

الأن في جملة eloquent نستخدم العلاقة الجديده

$users = User::with('lastPost')->first();


الدالة oldestOfMany في لارافيل

كذلك إذا أردنا الحصول على أول  Post قام الـ user بإنشاؤه، يمكن إستخدام oldestOfMany، حيث نقوم بإنشاء علاقة جديده مثلا بإسم oldestPost، وإيضا إستخدام العلاقة hasOne ومن ثم تمرير oldestOfMany

public function oldestPost()
{
    return $this->hasOne(Post::class)->oldestOfMany();
}
$users = User::with('oldestPost')->first();


الدالة ofMany في لارافيل

كما شاهدنا بالأعلى أنا الدوال latestOfMany و oldestOfMany تقوم بإرجاع أول سجل و أخر سجل، لكن ببعض الأحيان قد يتطلب الأمر إسترجاع سجلات بشروط أخرى، على سبيل المثال إذا أردنا إرجاع user post التي لها أعلى عدد من المشاهدات.

هنا ننشئ علاقة مثلا بإسم popularPost ونستخدم ofMany ونمرر لها الحقل الذي نريد الترتيب من خلالة (views, id, updated_at...)، ومن ثم الدالة min, max، في حالتنا بما إننا نريد عدد المشاهدات سوف نستخدم الحقل views

public function popularPost()
{
    return $this->hasOne(Post::class)->ofMany('views', 'max');
}
$users = User::with('popularPost')->first();


كما يمكن أيضا إستخدام clousure function كـ second argument ، مثلا إذا كنا نريد جلب user post التي لها أعلى عدد من المشاهدات ، لكن المشاهدات أقل من 1000.

public function popularPost()
{
    return $this->hasOne(Post::class)
        ->ofMany(['views'=>'max'], function ($q){
            $q->where('views','<','200');
        });
}
$users = User::with('popularPost')->first();


مثال أخر: لفرض أردنا أن نجلب أخر post من حيث id , وأن يكون أخر post تم التعديل عليه.

public function maxUpdatedAtOrder(){
    return $this->hasOne(Post::class)->ofMany(['id'=>'max', 'updated_at'=>'max']);
}


مثال أخر : لفرض أردنا أن نجلب أخر post من حيث id و يكون أخر post تم التعديل عليه، ويكون العنوان يحتوي على كلمة palestine

public function maxWithCondition(){
    return $this->hasOne(Post::class)
        ->ofMany(['id'=>'max', 'updated_at'=>'max'], function ($q){
            $q->where('title','like','%palestine%');
        });
}



التعليقات
mahmoud
منذ سنة

very good

واثق الشويطر
منذ سنة

مقال جميل جدا.. مبارك التصميم الجديد للمدونة.. عندي ملاحظة بسيطة وهي تغيير الخط في الكود إلى خط monospace كما في محررات الكود، فهذا أسهل في القراءة

مصطفى النمر
منذ سنة

بارك الله فيك و زادك من علمه مقال جميل و مفيد و نتمنى المزيد

Eslam
منذ سنة

مقال ممتاز وموضوع مش كتير واخد باله منه شكرا جدا وجزاك الله خيرا

saeed
منذ سنة

شكرا لك ، سؤالي هل لابد من استخدام ( العلاقة ) قبل البحث ؟ الا يكفي في laravel استخدام mysql select statment فقط

tohami
منذ سنة

مقال تحفة ربنا يكرمك

إضافة تعليق
Loading...