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

السؤال

Recommended Posts

  • 0
نشر

عند الوصول لعلاقات Eloquent كخاصيات يتم تحميل بيانات تلك العلاقات بشكل كسول، أي بشكل لحظي سيتم تنفيذ الإستعلام عند الوصول لجلب بيانات العلاقة، و هذا الأمر يُسبب خلل في أداء التطبيق حيث أن كثرة الإستعلامات تُؤدي إلى بطئ التطبيق في الإستجابة حيث أن هذا الأمر يُسبب مشكل مشهورة في لارافل إسمها مشكلة N + 1، لكن يُمكن في Eloquent تحميل بيانات العلاقة بشكل حثيث أي مُسبق و هذا هو حل تلك المُشكلة و يتم إستخدام كل من التابع load او التابع with.

مثال لنفترض أنه لدينا النموذج Category و النموذج Post حيث أن كل مقال ينتمي إلى قسم و كل قسم به عدة مقالات:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
   /**
    * ...
    */
   public function category()
   {
       return $this->belongsTo(Category::class);
   }
}

لنجلب الآن كل المقالات و نحاول طباعة القسم:

$posts = App\Models\Post::all();

foreach ($posts as $post) {
   echo $post->category->name;
}

سينفّذ هذا التكرار استعلام واحد لاسترداد كل المقالات و من أجل كل مقال سيتم تنفيذ إستعلام آخر لجلب بيانات القسم التابع له. فرضاً أنه لدينا 20 مقال فإنه سيتم تنفيذ إستعلام واحد لجلب كل المقالات و 20 إستعلام آخر لجلب القسم لكل مقال أي إجمالي 21 مقال، و هذا ما يُسمى بالتحميل الكسول، فإذا كان عدد المقالات N فإن عدد الإستعلامات التي ستُنفذ هو N + 1 و من هنا جاءت تسمية المشكلة.

لحُسن الحظ أنه يمكن إستخدام التحميل الحثيث الذي يسمح لنا بتقليل الإستعلامات إلى إستعلامين فقط و يُمكن تحديد العلاقة التي نريد تحميلها بشكل حثيث بإستخدام التابع with او load:

$posts = App\Models\Post::with('category')->get();

foreach ($posts as $post) {
   echo $post->category->name;
}

و هذا الشكل يؤدي إلى تنفيذ إستعلامين فقط:

select * from posts

select * from categories where id in (1, 2, 3, 4, 5, ...)

قد نُريد تحميل أكثر من علاقة بشكل حثيث فنُمررها في مصفوفة:

$posts = App\Models\Post::with(['category', 'auther'])->get();

قد نُريد تحميل حقول محددة فقط:

$posts = App\Models\Post::with('category:id,name')->get();

و هناك عدة نقاط و مفاهيم أخرى يُمكنك الإطلاع على التوثيق الرسمي لمعلومات أكثر.

  • 0
نشر
بتاريخ 12 دقائق مضت قال hanan fahad11:

فهمت فكره with لاكن الثانيه مافهمتها ممكن مثال ري with اقدر اطبق عشان افهم 

هما نفس الشيء يخدمان التحميل الحثيث لكن load تستخدم لتحميل العلاقة بعد تحميل النموذج الأب و تستخدم لفصل الإستعلامين مثلاً قد نحتاج لتحميل بيانات العلاقة في حال تحقق شرط ما:

$posts = App\Models\Post::all();

if (some_condition) {
   $posts->load('relation1', 'relation2');
}

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

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

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

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   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.

  • إعلانات

  • تابعنا على



×
×
  • أضف...