[Laravel 5] 筆記16 Many to Many Relations (With Tags)

2015-03-17

https://laracasts.com/series/laravel-5-fundamentals/episodes/21

本節以 articles 對 tags 練習
一個 article 有很多 tags
一個 tag 也可以對上很多 articles
 
▼ app/Article.php

    // 增加這個關連
    public function tags()
    {
        // 因為可以有很多 tags 所以是 belongsToMany
        // withTimeStamps() 是因為要讓 created_at updated_at 欄位會自動處理
        return $this->belongsToMany('App\Tag')->withTimestamps();
    }

 
使用 artisan 建立 model 檔案

php artisan make:model Tag

(沒有 migrate 檔案的話 會自動建立一個[建立 Tags table]的 migrate 檔案)
 
▼ database/migrations/2015_03_17_023757_create_tags_table.php

class CreateTagsTable extends Migration {
	public function up()
	{
		// 建立 tags table 這邊還有一個 name 欄位
		Schema::create('tags', function(Blueprint $table)
		{
			$table->increments('id');
			$table->string('name');
			$table->timestamps();
		});
		
		// 另外還要一個中介的 table 名稱是這兩個 model 名稱中間加一個底線 英文字母排前面的放前面 ( a 排在 t 前面 所以 article 放前面)
		Schema::create('article_tag', function(Blueprint $table)
		{
			// 數字 正數 同時也要設 index
			$table->integer('article_id')->unsigned()->index();

			// 刪除 article 的時候同時也要刪除這個中介用的資料 所以要設定 foreign			
			$table->foreign('article_id')->references('id')->on('articles')->onDelete('cascade');
			
			// 同 article_id
			$table->integer('tag_id')->unsigned()->index();
			$table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade');

			// created_at, updated_at 會自動處理
			$table->timestamps();
		});
	}

	public function down()
	{
		// rollback 則是將兩個 table drop 掉
		Schema::drop('tags');
		Schema::drop('article_tag');
	}

}

使用 artisan 執行 migrate

php artisan migrate

 
▼ app/Tag.php

    // 這邊同樣也要增加關連
    public function articles()
    {
        return $this->belongsToMany('App\Article');

        // 如果要自己設定中介 table 的名稱 可以加在第二個參數 這邊示範即是設定成 tags_pivot
        // 如果要自己另外設定 article_id 則是加在第三個參數 這邊示範設定成 article_identifier
        return $this->belongsToMany('App\Article', 'tags_pivot', 'article_identifier');
    }

 
兩者關係建立好後 以下幾個例子

// 取得一個示範用的 article
$article = App\Article::first();

// 將 article 跟 tag 連接起來 要在中介的 table 增加一筆資料
// 以下就是將 tag id = 1 ( attach ) 的跟前一行取得的 article 的連起來
$article->tags()->attach(1);

// 執行下面這行後
$article->tags();
// $article 裡即會有 tags
// tags 物件會有一個 key 為 pivot 的中介 table 資料

// 以另一邊示範的話
$tag = App\Tag::first();
// 同樣也可以獲得屬於這個 tag 的 articles
$tag->Articles();