آموزش لاراول – رابطه Many to Many

  • خانه
  • آموزش لاراول – رابطه Many to Many
Image تحقیقات

آموزش لاراول – رابطه Many to Many

با سلام و درود خدمت شما دوستان عزیزم

در ادامه آموزش های فریم ورک لاراول  ، امروز توضیح کاملی درباره رابطه چند به چند یه N به N و یا به عبارتی Many to Many Relationships in Laravel می دهیم.

مثال خوبی که برای این رابطه می تونیم بزنیم  ، رابطه ی بین پست ها و تگ ها می باشد.(شما می توانیم تگ را همان دسته بندی فرض کنید)

در واقع هر پست می تواند چندین تگ (دسته بندی) داشته باشد و هر تگ  نیز مربوط به چند پست باشد.

در این آموزش ما دو تا جدول (Table) داریم به نام های Blog Posts که پست ها در داخل آن ذخیره خواهند شد و Tags که تگ ها (دسته بندی ها) در آن ذخیره خواهند شد و در ادامه جدول واسط دیگریبه نام  blogpost_tag  نیز ایجاد خواهیم کرد.در این جدول واسط (pivot table) ، مشخص میکنیم کدام تگ مربوط به کدام پست می باشد.

فرض کنید جدول تگ ها مانند زیر باشد.

+----+-----------+---------------------+---------------------+
| id | name      | created_at          | updated_at          |
+----+-----------+---------------------+---------------------+
|  1 | laravel   | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 |
|  2 | bootstrap | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 |
|  3 | windows   | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 |
+----+-----------+---------------------+---------------------+

و جدول واسط ما (pivot table) مانند زیر باشد.

+----+-------------+--------+
| id | blogpost_id | tag_id |
+----+-------------+--------+
|  1 |           1 |      2 |
|  2 |           2 |      2 |
|  3 |           3 |      1 |
|  4 |           4 |      1 |
|  5 |           4 |      3 |
|  6 |           5 |      3 |
+----+-------------+--------+

در جدول بالا مثلا مشخص شده  :

تگی با آیدی 1 مربوط به پستی با آیدی 1 می باشد.

تگی با آیدی 2 مربوط به پستی با آیدی 2 می باشد.

و یا مثلا پستی با آیدی 4 دارای 2 تگ با ایدی های 4 و 5  می باشد.

خب همانطور که می دانید در فریم ورک لاراول هر جدول باید یک model داشته باشد که در داخل آن روابط امون رو تعیین خواهیم کرد.

یک model به نام blogpost تعریف میکنیم  و در آن تعیین می کنیم که  جدول blogpost با جدول Tags رابطه چند به چند دارد. برای این کار کد زیر را به model امون اضافه می کنیم.

class Blogpost extends Eloquent {
	protected $guarded = array();
	
	public function tags() {
		return $this->belongsToMany('Tag');	
	}
}

 

  •  در خط شماره 4 تابعی ساختیم به نام tags  که  و در داخل این تابع با استفاده از متد  belongsToMany تعیین کردیم که جدول blogpost یا همان پست هامون ، یک رابطه چند به چند به جدول tag دارد.

خب حالا میریم سراغ Model دیگمون که مربوط به جدول tag است.

class Tag extends Eloquent {
	protected $guarded = array();
	
	public function blogposts() {
		return $this->belongsToMany('Blogpost');
	}
}

 

  •  در خط 4 تابع ای دیگر با نام دلخواه blogposts تعریف کردیم و در داخل این تابع گفاتیم که این modal (یعنی همان  جدول tag) رابطه ی چند به چند با جدول Blogpost دارد.

تا این جای کار ما رابطه ی بین جداولمون رو تعیین کردیم. حالا میخوایم ببینیم این رابطه چه کاربردی دارد.

تصور کنید میخواهید پست هایی را نمایش دهید که دارای تگی با آیدی 1 می باشند.برای این کار میتوایند کد زیر را در فایل route بنویسید.

Route::get('/', function()
{
    $tag = Tag::find(1);
	return $tag->blogposts;
});

 

  •  در خط سوم : مشخصات تگی با آیدی 1 را از جدول استخراج کردیم.
  • در خط چهارم : با استفاده از همان رابطه ای که در modal نوشتیم. پست های مروبط به این تگ را استخراج کردیم.

خروجی کار مانند زیر می شود :

[
 
    {
        "id": 3,
        "title": "Laravel Eloquent ORM Tutorial",
        "body": "Eloquent is the very powerful and expressive ORM or Object Relational Mapper in Laravel. If you know how to work with Objects in PHP, then you know how to use Eloquent! ",
        "created_at": "0000-00-00 00:00:00",
        "updated_at": "0000-00-00 00:00:00",
        "pivot": {
            "tag_id": 1,
            "blogpost_id": 3
        }
    },
    {
        "id": 4,
        "title": "Install Laravel on Windows",
        "body": "This is going to assume we are starting from scratch using a fresh install of WAMP 2.4 on Windows.",
        "created_at": "0000-00-00 00:00:00",
        "updated_at": "0000-00-00 00:00:00",
        "pivot": {
            "tag_id": 1,
            "blogpost_id": 4
        }
    }
 
]

 

در خروجی بالا گفته شده پست هایی با آیدی 3 و 4 تگ مورد نظر را دارا می باشند.

حالا یه مثال دیگر میزنیم.

همین کار را برای تگی با آیدی 2 انجام میدهیم.

Route::get('/', function()
{
    $tag = Tag::find(2);
	return $tag->blogposts;
});

خروجی مانند  زیر می شود.

[
 
    {
        "id": 1,
        "title": "You Should Use Twitter Bootstrap!",
        "body": "If you are a design savvy person, you may have noticed that Vegibit uses the Twitter Bootstrap Framework. I freaking love this framework, and you should too, or rather if you’re unfamiliar, you will love it by the time you finish reading this article.",
        "created_at": "0000-00-00 00:00:00",
        "updated_at": "0000-00-00 00:00:00",
        "pivot": {
            "tag_id": 2,
            "blogpost_id": 1
        }
    },
    {
        "id": 2,
        "title": "Twitter Bootstrap Modal Tutorial",
        "body": "Modals are a fun way to add interactivity to your website. When a user needs to make a choice, or confirm an action, the classic jquery modal popup makes perfect sense.",
        "created_at": "0000-00-00 00:00:00",
        "updated_at": "0000-00-00 00:00:00",
        "pivot": {
            "tag_id": 2,
            "blogpost_id": 2
        }
    }
 
]

و حالا دنبال پست هایی هستیم که دارای تگی با آیدی 3 می باشند.

Route::get('/', function()
{
    $tag = Tag::find(3);
	return $tag->blogposts;
});

خروجی :

[
 
    {
        "id": 4,
        "title": "Install Laravel on Windows",
        "body": "This is going to assume we are starting from scratch using a fresh install of WAMP 2.4 on Windows.",
        "created_at": "0000-00-00 00:00:00",
        "updated_at": "0000-00-00 00:00:00",
        "pivot": {
            "tag_id": 3,
            "blogpost_id": 4
        }
    },
    {
        "id": 5,
        "title": "Install and Configure Windows Server 2012 with Windows Powershell",
        "body": "Windows PowerShell is an amazingly powerful tool to help you with common windows administrative tasks. If you are comfortable with one of the myriad of scripting languages available today, Powershell will be easy for you to learn while also providing the benefits of command line administration. ",
        "created_at": "0000-00-00 00:00:00",
        "updated_at": "0000-00-00 00:00:00",
        "pivot": {
            "tag_id": 3,
            "blogpost_id": 5
        }
    }
 
]

خب دیدین چه راجت بود.

حاالا کار رو برعکس میکنیم.یعنی میخوایم تگ هایی رو نمایش بدیم که مربوط به پستی با آیدی 4 می باشند.

Route::get('/', function()
{
    $blogpost = Blogpost::find(4);
	return $blogpost->tags;
})

خروجی نشان می دهد که تگ هایی با آیدی 3  و 1 مربوط به این پست می باشند.

[
 
    {
        "id": 1,
        "name": "laravel",
        "created_at": "0000-00-00 00:00:00",
        "updated_at": "0000-00-00 00:00:00",
        "pivot": {
            "blogpost_id": 4,
            "tag_id": 1
        }
    },
    {
        "id": 3,
        "name": "windows",
        "created_at": "0000-00-00 00:00:00",
        "updated_at": "0000-00-00 00:00:00",
        "pivot": {
            "blogpost_id": 4,
            "tag_id": 3
        }
    }
 
]

اضافه کردن یک سطر به جدول واسط (pivot table)

برای اضافه کردن سطری به جدول واسطمون می توانید از 2 متد attach و Sync استفاده نماییم.

متد attach برای موقعی استفاده می شود که شما می خواهید یک سطر جدید به جدول واسط اضافه کنید و مثلا بگین پستی با آیدی 4 دارای تگی با آیدی 2 می باشد.

برای این کار می توانیم از دستورات زیر استفاده کنیم.

Route::get('/', function()
{
    $blogpost = Blogpost::find(4);
    $blogpost->tags()->attach(2);
	
    return $blogpost->tags;
});

 

  •  در خط چهارم : تگ شماره 2 را با متد attach به جدول واسط امون اضافه کردیم.

خروجی :

[
 
    {
        "id": 1,
        "name": "laravel",
        "created_at": "0000-00-00 00:00:00",
        "updated_at": "0000-00-00 00:00:00",
        "pivot": {
            "blogpost_id": 4,
            "tag_id": 1
        }
    },
    {
        "id": 2,
        "name": "bootstrap",
        "created_at": "0000-00-00 00:00:00",
        "updated_at": "0000-00-00 00:00:00",
        "pivot": {
            "blogpost_id": 4,
            "tag_id": 2
        }
    },
    {
        "id": 3,
        "name": "windows",
        "created_at": "0000-00-00 00:00:00",
        "updated_at": "0000-00-00 00:00:00",
        "pivot": {
            "blogpost_id": 4,
            "tag_id": 3
        }
    },
    {
        "id": 4,
        "name": "wamp",
        "created_at": "2014-02-04 17:32:36",
        "updated_at": "2014-02-04 17:32:36",
        "pivot": {
            "blogpost_id": 4,
            "tag_id": 4
        }
    }
 
]

 

س متد attach میاد یه سطر جدید اضافه میکنه و کاری به سطر های قبلی جدول واسط ندارد.

متد دیگری که برامون همین کار رو انجام میده Sync می باشد.این متد هم  یه سطر به جدول واسط اضافه می کند ولی سطر های قبلی جدول واسط که مربوط به همان پست باشد را پاک می کند.

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

Route::get('/', function()
{
    $blogpost = Blogpost::find(4);
    $blogpost->tags()->sync(array(1,2,3,4));
	
    return $blogpost->tags;
});
//  This blogpost now has all tags associated with it

 

  • در این مثال متد sync  ابتدا در جدول واسط تمام سطر هایی که مروبط به پستی با آیدی 4 است را پاک می کند سپس  در خط چهارم با استفاده از متد sync تگ هایی با آیدی 1 و 2 و3 و 4  به پستی با آیدی 4 اختصاص می یابد.

پس متد sync همانند متد attach است با این تفاوت که سطرهای جدید را اضافه می کند و در عین حال سطرهای قبلی رو پاک می کند.

مثال :

Route::get('/', function()
{
    $blogpost = Blogpost::find(4);
    $blogpost->tags()->sync(array(1));
	
    return $blogpost->tags;
});
//  The same blogpost now has only tag with id of 1 assigned to it

در مثال بالا تگی با آیدی 1 به پستی با ایدی 4 اختصاص پیدا می کند (در جدول واسط) و مابقیه سطرهای این جدول که مربوط به این پست بوده پاک خواهد شد.

امیدوارم تونسته باشم شما را با این مبحث آشنا کرده باشم.

تا آموزش لاراول  بعدی ، موفق باشید.