Laravel多對多關係詳解【文章 - 標籤】

  • 2019 年 11 月 13 日
  • 筆記

前言

今天弄了一天的關於文章的功能,其中主要卡在文章與標籤的多對多的關係糾結中。卡了半天,終於算是解決了,不是很完美,但可以。

新建遷移文件

多對多的關係中,需要三張表。兩張主體表、一張這兩張表的關係表。

這是我是文章表【articles】、標籤表【tags】以及關係表【article_tag】

其中關係的命名是[article_tag]而不是tag_article 因為laravel默認是以字母升序排列。可以在定義的時候設置,但何必那麼麻煩,按照默認規則來不是很好么?

另外就是,新建遷移文件的順序也有要求,關係表肯定是最後的,然後文章表和標籤表好像隨意,但我是先建文章表。

新建文章表

php artisan make:model Model/Article -m

我是新建模型的時候就順帶穿件遷移表了。可以直接php artisan make:migration create_articles_table --create=articles創建。

這裡有外鍵,但是是其他外鍵,不關我們這裡要講的。

新建標籤表

php artisan make:model Model/Tag -m

我是新建模型的時候就順帶穿件遷移表了。

可以看出沒有外鍵。

新建關係表

php artisan make:migration create_article_tag_table --create=article_tag

這裡有兩個外鍵,分別是文章表的主鍵和標籤表的主鍵。

foreign()外鍵

references():參照欄位

on():參照表

onDelete():刪除時的執行動作

這裡是跟著刪除,比如刪除了某篇文章,我們將article_tag中包含article_id一樣的記錄也刪除

執行遷移

php artisan migrate

聲明Eloquent的關係

Article

Tag

我們使用 $this->belongsToMany() 來表明Eloquent的關係,這裡需要注意的是如果你的外鍵並不是 article_id 和 tag_id ,你需要在第三個參數進行設置,寫成類似下面這樣:

public function articles()  {      return $this->belongsToMany('AppArticle','conversation_id');  }

創建文章和標籤

就是在這裡卡了半天。

我先的寫法是:

$article = Article::create([      'title' => $input['title'],      'content' => $input['content'],      'category_id' => $input['category_id'],      'introduction' => $input['introduction'],      'author_id' => $input['author_id'],  ]);  $article->tags()->firstOrCreate(['name'=>'tag name']);

嗯,不行,每次創建文章,哪怕標籤都一樣的,但還是會在tag表新建一個標籤。

類似這樣:

後來經過查閱多方資料以及官方文檔,才發現,想要標籤表中的值唯一,而關係表中通過tag_id來標記不能這樣寫。

而正在的寫法是:

$article->tags()->attach($tags);

傳入的$tags 不是名稱,而是tag表的id,可以是數組

????而我不能在新建文章時直接輸入標籤名????

於是,系統新建標籤的頁面就被我改成這樣了:

Tags: