پشت پرده with در روابط n-n
در جلسه قبلی ار روال کار در روابط n-1 باخبر شدیم و کاری که لاراول انجام میده ولی در روابط n-n به دلیل داشتن جدول واسط (pivot) پیچیدگی بیشتری نسبت به روابط قبلی وجود داره در این روابط برای لاراول ابتدا به جدول واسط join میزند و از جدول واسط به وابستگی چگونه ما میتوانیم از پشت پرده کوئری های که اجرا میشود باخبر شویم ؟! بهترین راه استفاده از متد listenدر کلاس DB است
DB::listen(function ($query){
$query->sql ;
$query->binding ;
$query->time ;
});
در بالا ما میتوانیم از متغییر query , زمان اجرا کوئری و همچنین کد sql و متغییر های bind شده به کوئری خودمون رو بگیریم بهترین کار برای انالیز فعالیت ها دیتابیس شما
روابط n-n در دنیای واقعی :
ما در نظر میگیریم سه جدول با نام های permissions , roles , permissions_role داریم structure زیر رو در نظر بگیرید
زمانی که ما میخواهیم پرمیشن های یک role رو به دست بیاریم ما باید از roles به وسیله جدول واسط به پرمیشن برسیم مثلا
SELECT permissions.* FROM roles
JOIN permission_role ON roles.id = permission_role.role_id
JOIN permissions ON permission_role.permission_id = permissions.id
WHERE roles.id = 1
در کد بالا روال join زدن پشت هم و رسیدن به هدف رو میبنید ! ما در کد بالا پرمیشن های role = 1 رو پیدا میکنیم ولی این تمام ماجرا نیست
withCount در روابط n-n :
در رابط چند ب چند withcount مانند روابطه یک ب چند کار میکند و نیازی ندارد ما حتما به جدول permissions برسیم فقط زمانی که جدول خواستار این بودیم که برای permission های هر رول شرطی بزاریم رسیدن به این جدول الزامیس به دو نمونه کد زیر دقت کنید :
SELECT roles.* , COALESCE(permissions_count , 0 ) AS permissions_count
FROM roles
LEFT JOIN (
SELECT count(*) as permissions_count ,role_id
FROM permission_role
GROUP BY permission_role.role_id
) AS pivot
ON roles.id = pivot.role_id
SELECT roles.* , COALESCE(permissions_count , 0 ) AS permissions_count
FROM roles
LEFT JOIN (
SELECT COUNT(*) AS permissions_count , permission_role.role_id
FROM permissions
JOIN permission_role
ON permission_role.permission_id = permissions.id
GROUP BY role_id
) AS pivot
ON roles.id = pivot.role_id
در دو کد بالا مهمترین تفاوت این است در اولین کد ما بدون در نظر گرفتن جدول سوم جویین میزنیم ولی در کد دوم ما جدول سوم رو در نظر میگیریم و حتی میتوانیم فیلتر های where یا هر چیز دیگری رو داخلش اعمال کنیم فرق اصلی این دو کد در این است .