محتويات الدورة

Laravel / حدود التطبيق وسير العمل الموثوق / الدرس 7

العلاقات والاستعلام المقصود

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

وقت القراءة التقريبي: 3 دقيقةتاريخ مراجعة المحتوى
في هذه الصفحة

أهداف الدرس

  • وصف التعدد والملكية أولا
  • إعلان عقد المفتاح الخارجي
  • مراجعة النطاق والترتيب والكلفة

وصف التعدد والملكية أولا

تعبر العلاقة عن ارتباط مجال لا اسم خاصية مناسب فقط. ينتمي Post إلى User عبر posts.user_id، وللمستخدم منشورات كثيرة. تحمي المفاتيح سلامة المرجع وتفيد الفهارس البحث ولا تمنح القراءة. حدد إلزام العلاقة ومعنى الحذف وإظهار الأب المحذوف منطقيا، فتؤثر القرارات في المخطط والتحقق والتفويض. لا تستنتج الملكية التجارية لمجرد كائن محمل.

تمييز استعلام العلاقة من قيمتها المحملة

تعيد author() كائن علاقة يبني استعلاما، بينما تقرأ author القيمة وقد تحملها كسولا. تبني posts() قيدا وتمثل posts مجموعة بعد الحل. يهم الفرق في الحلقات والتسلسل؛ فقد ينفذ الوصول عمل قاعدة. ضع التصفية قبل الجلب، لأن تصفية المجموعة بعد get لا تقلل SQL أو ذاكرة التحميل بأثر رجعي.

إعلان عقد المفتاح الخارجي

ينتمي المقطع إلى App\Models\Post في تطبيق تدريبي بجدول يحوي الحقول المذكورة. يسمي user_id لأن العلاقة author وإلا قد تفترض author_id. تدعم HasFactory مصانع نعرفها لاحقا ولا تنشئها. ينبغي أن يستخدم عكس User العلاقة hasMany(Post::class, "user_id"). لا ينشئ تعريف الطريقة قيدا أو بيانات تلقائيا.

php مقطع سياقي لتطبيق Laravel 12
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Post extends Model
{
    use HasFactory;
    protected $fillable = ["title", "body", "published"];
    public function author(): BelongsTo
    {
        return $this->belongsTo(User::class, "user_id");
    }
}
الناتج المتوقع
For Post user_id=7, author() targets User primary key 7.

يتطلب المخطط والمستخدم المذكورين ويربط المفتاح الصريح author() بحقل user_id.

تحميل الرسم المطلوب بعمل محدود

يجلب الثاني عشرة منشورات منشورة كحد أعلى ويحمل معرف المؤلف واسمه، ويحفظ user_id ومعرف الأب للمطابقة. في عينة منشور ظاهر لميرا وآخر مسودة لعمر يظهر الأول وحده. يتجنب التحميل المعتاد استعلام المؤلف لكل صف، وقد تغير النطاقات العدد الفعلي. اختر الأعمدة بعناية واستخدم withCount للعدد وافحص الدليل لا حجم الرد.

php مقطع سياقي لتطبيق Laravel 12
<?php
use App\Models\Post;
$posts = Post::query()
    ->where("published", true)
    ->with("author:id,name")
    ->orderBy("id")
    ->limit(10)
    ->get(["id", "user_id", "title"]);
الناتج المتوقع
Synthetic fixture result: post 1; loaded author Mira.

يوفر المتحكم السياق، وتضم العينة المنشور الأول ومؤلفته فقط مع استبعاد المسودة.

مراجعة النطاق والترتيب والكلفة

طبق نطاق الرؤية والمستأجر قبل التحميل والترقيم، واجمع OR كي لا يخرج عن الملكية. رتب حتميا وحد الطلب. قد يستبدل تحميل كل العلاقات مشكلة N+1 بذاكرة وصفوف زائدة، فحمّل المطلوب. اختبر الغياب والفراغ وتكرار الربط والاستبعاد. المراجعة والعينات المعزولة كافيتان ولا تنفذ على قاعدة التطبيق المعدة.

الأخطاء الشائعة وإصلاحها

تستعلم author_id

لماذا يحدث؟
اختلف الاسم الاصطلاحي عن المخطط.
كيف تصلحه؟
صرح user_id في belongsTo.
كيف تتجنب تكراره؟
طابق المخطط والأسماء والمفاتيح.

تستعلم القائمة مؤلفا لكل صف

لماذا يحدث؟
قرئت علاقة كسولة بحلقة.
كيف تصلحه؟
حمّل المطلوب قبل العرض.
كيف تتجنب تكراره؟
افحص العمل مع عدة صفوف.

تبدو العلاقات فارغة بعد تقليل الأعمدة

لماذا يحدث؟
أغفلت مفاتيح المطابقة.
كيف تصلحه؟
احفظ مفاتيح الربط.
كيف تتجنب تكراره؟
اختبر اختيار الأعمدة بعينات العلاقات.

اختبر فهمك

1. تحتاج الصفحة اسم المؤلف وعدد التعليقات فقط. صمم التحميل.

اعرض الحل المشروح

حمّل المؤلف مع مفاتيح المطابقة واستخدم withCount("comments") دون كل التعليقات. احفظ نطاق النشر والوصول وافحص العمل بعينة معزولة.

2. لماذا لا تعادل تصفية مجموعة محملة شرط where بقاعدة؟

اعرض الحل المشروح

تحدث بعد الجلب والتخصيص وقد تعطي الشكل نفسه بكلفة زائدة ولا تعوض نطاق الوصول. اختر الحد بالكلفة وعقد الرؤية.

أهم ما تعلمته

  • للطريقة والقيمة المحملة كلفتان مختلفتان.
  • احفظ مفاتيح المطابقة.
  • لا يعوض التحميل سياسة الوصول.

المراجع الرسمية