آموزش رابطه ها در لاراول

آموزش رابطه ها در لاراول

در این مقاله درمورد آموزش رابطه ها در لاراول بحث خواهیم کرد. معمولا جدول ها در دیتابیس یا پایگاه داده، با هم در ارتباط هستند. مثلا در یک وبلاگ، یک نوشته می تواند چندین دیدگاه یا کامنت داشته باشد. در عین حال همین نوشته با کاربری که آن را نوشته و ثبت کرده است نیز ارتباطی دیگر دارد. Eloquent نوشتن این روابط و کار با آنها را بسیار آسان تر کرده است. مخصوصا که از انواع ارتباط به خوبی پشتیبانی می کند. برای آموزش رابطه ها در لاراول باید تمام انواع رابطه ها را مطالعه نمایید:

  1. One To One رابطه یک به یک
  2. One To Many رابطه یک به چند
  3. Many To Many رابطه چند به چند
  4. Has One Through رابطه یک به یک با واسطه
  5. Has Many Through رابطه یک به چند با واسطه
  6. One To One (Polymorphic)
  7. One To Many (Polymorphic)
  8. Many To Many (Polymorphic)

آموزش رابطه ها در لاراول

رابطه های Eloquent با نوشتن متد ها در داخل Model های Eloquent تعریف می شوند. به عبارتی برای تعریف هر رابطه شما باید در داخل کلاس مدل هایتان، اقدام به نوشتن متد یا تابع یا فانکشن نمایید.  دقیقا همانند مدل های  Eloquent، رابطه ها نیز خود به عنوان یک query builder عمل می کنند، تعریف رابطه ها به صورت توابع یا همان متد ها این امکان را فراهم می کند تا اطلاعات را به صورت زنجیره ای از پایگاه داده صدا زده و قابلیت های پرس و جوی بیشتری را در جستجوهای خود به کار بگیرید. مثلا :

در مثال بالا مشاهده می کنید که توانستیم جستجوی پیشرفتهای در بین پست های یک کاربر انجام دهیم. به عبارتی باید گفت که می توانیم از متد های Eloquent در روابط لاراول بهره برده و پرس و جوی دقیق تری انجام دهیم.

آموزش رابطه ها در لاراول را با مطالعه روابط ساده شروع می کنیم :

 رابطه یک به یک یا One To One در لاراول

ساده ترین و اساسی ترین رابطه در لاراول، رابطه یک به یک می باشد. مثلا هر کاربری فقط یک شماره موبایل دارد و هر شماره موبایلی می تواند فقط متعلق به یک کاربر باشد نه بیشتر.

پیاده سازی

اگر جدول users یا کاربران به این صورت باشد :

جدول mobiles  نیز باید اینگونه باشد :

در سطر سوم از دستورات بالا، به عبارت user_id کلید خارجی یا foreign key می گویند. مقدار این عبارت برابر خواهد بود با id کاربر. با استفاده از مقدار کلید خارجی مشخص می شود که یک شماره تلفن متعلق به کدام کاربر است.

در مدل User :

در مدل Phone :

بعد از انجام مراحل بالا کافیست جدول را نهایی کنیم :

حال برای فراخوانی شماره موبایل یک کاربر می توانیم دستور زیر را بکار ببریم :

و یا :

و همچنین برای فراخوانی کاربر مربوط به یک شماره تلفن :

و یا :

نکته :

کلید خارجی یا foreign key  را می توانید چیزی به جز user_id نیز قرار دهید اما باید در متد phone() در مدل User و نیز در متد user()  در مدل Phone به این مطلب اشاره کنید. فرض کنید ما از عبارت person_id استفاده کرده ایم :

در  مدل User :

و در مدل Phone  :

جهت آموزش کامل و کاربردی رابطه یک به یک، به این آدرس مراجعه بفرمایید.

 

رابطه یک به چند یا One To Many در لاراول

رابطه یک به چند زمانی تعریف می شود که یک مقدار از یک مدل Model دارای چند مقدار از مدل های دیگر است. به طور مثال در یک سایت خبری، هر پست یا خبر، چندین و چندین comment یا دیدگاه دارد و در عین حال دیدگاه ، فقط متعلق به یک خبر است.

پیاده سازی :

اگر جدول posts  یا مطالب به این صورت باشد :

جدول comments  یا دیدگاه ها نیز باید اینگونه باشد :

در سطر سوم از دستورات بالا، به عبارت post_id کلید خارجی یا foreign key می گویند. مقدار این عبارت برابر خواهد بود با id مطلب یا post مربوطه. با استفاده از مقدار کلید خارجی مشخص می شود که یک دیدگاه یا کامنت متعلق به کدام پست است.

در مدل Post :

در مدل Comment :

بعد از انجام مراحل بالا کافیست جدول را نهایی کنیم :

حال برای فراخوانی کامنت ها یا دیدگاه های یک پست یا مطلب می توانیم دستور زیر را بکار ببریم :

و یا :

و همچنین برای فراخوانی مطلب مربوط به یک دیدگاه :

و یا :

نکته اول :

دقت کنید که در مدل Post  نام متد را  comments به صورت اسم جمع دادیم، زیرا هر پست یا مطلب می تواند بیش از یک دیدگاه یا کامنت داشته باشد.

نکته دوم :

کلید خارجی یا foreign key  را می توانید چیزی به جز post_id نیز قرار دهید اما باید در متد comments() در مدل Post و نیز در متدpost()   در مدل Comment به این مطلب اشاره کنید. فرض کنید ما از عبارت relation_id استفاده کرده ایم :

در مدل Post :

و در Comment.php  :

جهت آموزش کامل و کاربردی رابطه یک به چند، به این آدرس مراجعه بفرمایید.

Many To Many رابطه چند به چند در لاراول

فرض کنید ما جدولی داریم به نام tags که بالطبع نام مدل آن Tag است و جدولی به نام posts که اسم مدل آن Post می باشد. حال فرض کنید یک post نوشته ایم  به نام “روابط در لاراول”  که می تواند این تگ ها را به خود اختصاص دهد : php , laravel , برنامه نویسی , …

حال هر یک از تگ های بالا می توانند در پست های زیادی باشند. مثلا پستی با عنوان “سیستم احراز هویت لاراول” هم می تواند تگ php یا laravel را بگیرد. پس هر post  میتواند چندین tag داشته باشد و هر tag می تواند متعلق به چندین  post باشد. بدین ترتیب دو جدول posts و tags می توانند رابطه many to many  داشته باشند.

پیاده سازی 

در رابطه Many To Many  به غیر از جداول posts  و tags  ، به جدول واسطه دیگری نیازمندیم که به آن pivot table  نیز گفته می شود. در واقع در هیچ یک از جداول posts  و tags نیاز به تعریف کلید خارجی نداریم و این کار را تنها در جدول واسطه انجام خواهیم داد. ابتدا جداول posts  و tags را تعریف می کنیم :

جدول posts  :

جدول tags :

نوشتن جداول واسطه مهم ترین بخش از آموزش رابطه ها در لاراول می باشد.حال نوبت به طراحی و تعریف جدول واسطه یا pivot table  می رسد.

  1. اولین نکته در طراحی این جدول نام آن است. نام جدول واسطه باید از ترکیب نام دو جدول که رابطه many to many دارند ساخته شود.
  2. نام جدول واسطه باید ترکیب اسم مفرد جدول اول و اسم مفرد جدول دوم با یک آندرلاین (خط زیرین یا underscores) در میان آنها باشد. مثلا post_tag . درواقع اسم posts_tags برای نام pivot table  صحیح نیست.
  3. در انتخاب نام باید ترتیب الفبایی رعایت شود. بدین صورت که اسم جدولی در ابتدا نوشته می شود که حرف اول آن نسبت به حرف اول اسم جدول دیگر اولویت داشته باشد. مثلا اگر اسم جدول اول post باشد و اسم جدول دوم tags باشد با مقایسه دو حرف p  و t  به این نتیجه می رسیم که حرف p  نسبت به حرف  t  مقدم است. پس ابتدا باید post نوشته شود و سپس علامت _ و بعد tag  ، پس می شود : post_tag

مثال دیگر : نام جدول واسطه بین دو جدول  users  و roles  خواهد  شد :

role_user

مقادیر این جدول تنها id  های مقادیر دو جدول مربوط به هم و کلید های خارجی خواهند بود :

در مدل Post  :

در مدل Tag :

مجددا به جمع بودن اسم هر دو متد و عبارت belongsTo  در هر دوی آنها دقت نمایید .

جهت فراخوانی تگ های پست  با id = 3 می توان نوشت :

و برای فراخوانی پست های تگ با id=4  داریم :

Attach  ، Dettach  و Sync  در روابط many to many

الوکوئنت Eloquent   ، متد ها و helper هایی در اختیارمان گذاشته تا کار با رابطه many to many  آسان تر شود. یکی از این متد ها attach()  می باشد. Attach در لغت به معنای جسباندن و الصاق است و در لاراول جهت افزودن مدار به رابطه یک مقدار دیگر به کار می رود . مثلا :

مشاهده می فرمایید که ورودی متد attach() باید id  یا آرایه ای از id  ها باشد. این به خاطر این است که در pivot table  تنها id  می توان ذخیره کرد. در مثال دیگری می خواهیم چند tag  را به تگ های یک post اضافه نماییم :

و یا مثلا در تکه کد زیر :

متد detach()  نیز درست نقطه مقابل attach()  و برعکس آن عمل می کند. مثلا برای حذف یک یا چند مقدار از روابط یک مقدار دیگر. مثلا برای حذف tag  هایی با id های 1و2  از یک post  معین می توانیم بنویسیم :

چنانچه از متد sync()  استفاده نماییم، ابتدا تمام مقادیر حذف شده و سپس مقادیر ورودی متد sync() اضافه خواهد شد. مثلا فرض کنید post با id=3 تگ ها با id های 1و3 را دارد. چنانچه از دستور زیر استفاده کنیم:

تنها تگ با id=2 جزو تگ های این پست خواهد بود و تگ های 1و3  از جدول واسطه حذف خواهند شد. این helper  می تواند یک آرایه را نیز به عنوان ورودی بپذیرد.

کی اط قسمت های مهم آموزش روابط در لاراول روابط با واسطه است :

Has One Through رابطه یک به یک با واسطه در لاراول

رابطه hasOneThrough مدل ها را از طریق یک واسطه پیوند می دهد به عبارتی ایجاد ارتباط بین دو جدول یا دو مدل از طریق جدول یا مدل دیگری می تواند برقرار شود. مثلا فرض کنید در یک آژانس تلفنی جدولی به نام drivers یا راننده ها داریم. جدول دیگری هم  داریم به نام cars یا ماشین ها. جدول سومی نیز وجود دارد به نام car_infos  که مشخصات ماشین ها از قبیل شماره پلاک، رنگ و … را ثبت می کند و نام مدل مربوط به آن CarInfo می باشد. ارتباط بین دو جدول drivers  و cars  از نوع One To One است. و ارتباط بین دو جدول cars و car_infos نیز One To One است.

 یعنی هر راننده ای یک ماشین دارد و هر ماشینی یک اطلاعاتی و بالعکس هر اطلاعاتی متعلق به یک ماشین است و هر ماشینی متعلق به یک راننده. اما ارتباطی بین drivers  و car_infos وجود ندارد. برای ارتباط بین این دو جدول، در نسخه های قبل از 5.8 بایستی تغییراتی در هر دو جدول می دادیم و از کلید خارجی استفاده می کردیم اما از نسخه 5.8 به بعد این کار لازم نیست و ما میتوانیم با جدول های موجود ارتباط برقرار کنیم :

پیاده سازی

جدول drivers :

جدول cars :

جدول car_infos :

مشاهده می کنید که ارتباطی بین drivers  و car_infos وجود ندارد .

 برای ایجاد ارتباط بین این دو کافیست در مدل Driver :

این دستور می گوید: جدول drivers  با جدول car_infos ارتباط One To One دارد اما از طریق جدول cars .

برای فراخوانی شماره پلاک مربوط به راننده اول داریم :

ولی تا تاریخ تحریر این مقاله، لاراول برای این رابطه، رابطه برعکسی نگذاشته است به عبارتی نمی توان در این رابطه از روی اطلاعات یک ماشین، راننده آن را پیدا کرد. اما می توان در مدل CarInfo  این کار را انجام داد :

و برای فراخوانی راننده یک شماره ماشین :

Has Many Through رابطه یک به چند با واسطه در لاراول

رابطه hasManyThrough مدل ها را از طریق یک مدل واسطه ارتباط می دهد به عبارتی ایجاد ارتباط بین دو جدول یا دو مدل از طریق جدول یا مدل دیگری اتفاق می افتد.  فرض کنید یک جدول داریم به نام countries یا کشور ها با مدل Country  .جدول دیگری داریم به نام users یا کاربران با مدل User. جدول سوم هم متعلق به posts یا نوشته هاست که نام مدلش Post  می باشد.

ارتباط بین Country و User  به صورت One To Many است یعنی هر کشوری چندین کاربر دارد ولی هر کاربر تنها متعلق به یک کشور است.  ارتباط بین User و Post نیز چنین است. هر کاربر چندین پست دارد ولی هر پست تنها متعلق به یک کاربر است.

رابطه has many through می گوید می توانیم بین دو مدل Country و Post ارتباط برقرار کرده و همهpost های یک country  را فراخوانی نمود. تنها کافیست در مدل Country  :

این دستور می گوید : جدول countries  با جدول posts ارتباطی از نوع One To Many دارد اما از طریق جدول users .

حال برای فراخوانی همه post های یک کشور مشخص چنین عمل می کنیم:

ولی برای فراخوانی عکس این رابطه فعلا راهی جز نوشتن متد دستی وجود ندارد. مطابق مثال بالا می توان در مدل Post نوشت:

در این قسمت از مقاله آموزش روابط در لاراول نوبت به بررسی روابط Polymorphic  می رسد :

(One To One Polymorphic) رابطه پلی مورفیک یک به یک در لاراول

آموزش روابط در لاراول مستلزم درک صحیحی از روابط پلی مورفیک است. رابطه پلی مورفیک یک به یک مشابه رابطه ساده یک به یک است که در ابتدای مقاله بحث شد با این تفاوت که مدل هدف می تواند متعلق به چند مدل باشد و یا با چند مدل رابطه یک به یک داشته باشد.

فرض کنید مدلی داریم به نام Post  با این شرط که به دلیل محدودیت دیتابیس، در هر پست تنها قادر خواهیم بود از یک عکس استفاده کنیم. مدل دیگری نیز به نام User  داریم با این شرط که هر کاربر مجاز است تنها یک عکس داشته باشد. پس نیاز به مدل دیگری داریم به نام Image.

به عبارتی Image هم با Post رابطه یک به یک دارد هم با User. بنابراین می توانیم برای این سه مدل رابطه One To One از نوع Polymorphic بنویسیم :

پیاده سازی

جدول users  :

جدول posts :

جدول images :

در مدل User  :

در مدل Post :

در مدل Image :

برای فراخوانی عکس یک کاربر :

یا برای فراخوانی پست مربوط به یک عکس :

(One To Many Polymorphic) رابطه یک به چند پلی مورفیک

این رابطه شبیه رابطه One To Many یک به چند ساده است با این تفاوت که مدل هدف، می تواند می تواند با چند مدل ارتباط یک به چند برقرار کند.

فرض کنید در یک سایت هم تعدادی post به صورت متن و تکست داریم و هم تعدادی video که کاربران می توانند برای هر دوی اینها دیدگاه یا کامنت comment  بگذارند. به قولی دیگر مدل Comment  با هر دو مدل Post و Video ارتباط one to many  برقرار می کند.

به جای نوشتن چندین متد و کلید خارجی می توان از رابطه یک به چند پلی مورفیک استفاده کرده و از شلوغی در مدل ها و جدول ها جلوگیری کرد.

پیاده سازی :

جدول comments :

جدول posts :

جدول videos :

مدل Comment :

مدل Post :

مدل Video :

حال برای فراخوانی دیدگاه های یک پست :

و یا برای فراخوانی ویدیوی مربوط به یک دیدگاه :

(Many To Many Polymorphic) رابطه چند به چند پلی مورفیک

رابطه چند به چند پلی مورفیک اندکی پیچیده تر از بقیه رابطه هاست. از این رابطه زمانی استفاده می کنیم که یک مدل با چند مدل ارتباط چند به چند داشته باشد. مثلا مدل Tag با هر دو مدل Post و Video رابطه چند به چند دارد. به عبارتی هر ویدیو و پست تکست می تواند چندین تگ داشته باشد و  در عین حال هر تگ به صورت همزمان می تواند متعلق به چندین پست و ویدیو باشد.

اگر از رابطه Many To Many Polymorphic  استفاده نکنیم جدول ها و مدل هایمان کثیف و شلوغ خواهند شد. برای این رابطه علاوه بر سه جدول posts و videos و tags بایستی جدول دیگری به نام taggables نیز بنویسیم. این جدول چیزی مشابه جدول واسطه است.

 

پیاده سازی

جدول posts :

جدول videos :

جدول tags :

و اما جدول taggables :

در مدل Tag متدهای زیر را می نویسیم :

 در هر دو مدل Video و Post  متد زیر را می نویسیم :

برای فراخوانی تگ های یک پست :

یا جهت فراخوانی تگ های یک ویدیو :

ولی برای فراخوانی ویدیوهای مربوط به یک تگ :

آموزش رابطه ها در لاراول به صورت دقیق و مستحکم مستلزم مشاهده ویدیوهای آموزشی و تمرین و تکرار است. جهت آموزش کلی به آموزش صفر تا صد لاراول در همین سایت مراجعه فرمایید.

مراجع

https://laravel.com/docs/6.x/eloquent-relationships

https://medium.com/swlh/a-guide-on-laravel-relationships-1febfac430f6

https://appdividend.com/2018/05/16/laravel-model-relationships-example/

https://www.w3resource.com/laravel/eloquent-relationships.php

مطالب زیر را حتما بخوانید

دیدگاه ها

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

این سایت از اکیسمت برای کاهش هرزنامه استفاده می کند. بیاموزید که چگونه اطلاعات دیدگاه های شما پردازش می‌شوند.