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,可以是數組
????而我不能在新建文章時直接輸入標籤名????

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


