[Laravel 5 Fundamentals] 21 – Many-to-Many Relationships and Tags

來源:互聯網
上載者:User

多對多關係的 tag 案例

前言

上一節,我們對 flash message 的使用做一個講解,瞭解到什麼是 flash message,而且會進行簡單的使用。本節,我們對資料庫多對多的形式,以文章 tags 作為例子進行講解。

說明

開發環境:Windows 7

Laravel 版本: 5+

IDE: Phpstorm

資料庫在,之前我們就對 Laravel 的Eloquent 和Migration 做過兩節介紹,而且在Relationships 講過資料表之間的外鍵關係,那也是基本的一對多。

本節我們對資料庫中的多對多進行一個講解,而且所舉的例子就是 tags ,文章標籤。

tags 的引入

現在咱們部落格的準系統已經有了,寫文章,發表文章等。但是隨著文章越來越多,文章的篩選和管理就成了問題,要是能有 tag 標記每篇文章的關鍵詞,這對文章的管理將是一個很大的改善。

下面我們就來看一下 Eloquent 是怎麼實現給文章 tagging 的。

開啟的 Article.php ,還記得當初我們為每篇文章(Article)關聯作者(User)是在哪個方法嗎?算了,你也回答不了,就在最下面的 user() 方法,裡面寫了一句 belongsTo 就指明了文章所屬。該語句與 hasMany 是相對的,文章只能 belongsTo 一個作者,但是一名作者可以 hasMany 文章,就是這麼個關係。

但是在 tag 這裡,belongsTo 和 hasMany 就有點講不通了,一篇文章不能只 belongsTo 一個 tag ,應該是 belongsToMany tags 才通順。

所在在 user() 方法下面再價一個 tags() 方法,如下所示:

public function tags(){  return $this->belongsToMany('App\Tag');} 

下面呢,我們去建立一個 Tag Eloquent model吧。

建立 Tag model類和 Tag 表

在命令列下輸入命令:php artisan make:model Tag。

再在命令列下輸入命令: php artisan make:migration create tagtable –create=tags

開啟這個 create tagtable.php ,在這裡建立 tag 表的一些屬性或者說列:

public function up(){    Schema::create('tags', function (Blueprint $table) {        $table->increments('id');        $table->string('name');        $table->timestamps();    });    Schema::create('article_tag',function(Blueprint $table){        $table->integer('article_id')->unsigned()->index();        $table->foreign('article_id')->references('id')->on('articles')->onDelete('cascade');        $table->integer('tag_id')->unsigned()->index();        $table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade');        $table->timestamps();    });}public function down(){    Schema::drop('tags');    Schema::drop('article_tag');} 

之所以還同時建立一個 pivot table (即“ article_tag ”表),就是為了相當於一個快速尋找表,能把 article 和 tag 聯絡在一張表中,方便查取。

接下來對 migration 進行執行,在命令列中執行:php artisan migrate

接下來開啟 Tag.php,剛建立的。

既然 tag 和 Article 是多對多的關係,那麼在 Tag model 類中也應有一個指向 article 的方法:

public function articles(){     return $this->belongsToMany('App\Article');                        |} 

儲存後,開啟命令列,通過 tinker 來驗證是否成功:php artisan tinker

>>> $tag = new App\Tag;=> App\Tag {#646}>>> $tag->name='personal';=> "personal">>> $tag->save();=> true>>> App\Tag::all()->toArray();=> [    [      "id" => 1,      "name" => "personal",      "created_at" => "2016-04-30 13:48:49",      "updated_at" => "2016-04-30 13:48:49",    ],  ] 

關聯 article 和 tag

下面我們嘗試關聯一下這兩個表。

在 tinker 模式下:

>>> App\Tag::all()->toArray();=> [    [      "id" => 1,      "name" => "personal",      "created_at" => "2016-04-30 13:48:49",      "updated_at" => "2016-04-30 13:48:49",    ],  ]>>> $article=App\Article::first();=> App\Article {#659    id: "1",    user_id: "1",    created_at: "2016-03-20 15:05:18",    updated_at: "2016-03-20 15:05:18",    title: "譚曉龍建立的文章",    body: "真的是",    published_at: "2016-03-28 00:00:00",  }>>> $article->toArray();=> [    "id" => 1,    "user_id" => "1",    "created_at" => "2016-03-20 15:05:18",    "updated_at" => "2016-03-20 15:05:18",    "title" => "譚曉龍建立的文章",    "body" => "真的是",    "published_at" => "2016-03-28 00:00:00",  ]>>> $article->tags()->attach(1);Illuminate\Database\QueryExceptionwithmessage 'SQLSTATE[23000]: Integrity constraint violation: 19 NOT NULL constraint failed: article_tag.created_at (SQL: insert into "article_tag" ("article_id", "tag_id") values (1, 1))' 

這裡的 $article->tags()->attach(1),就是通過 tags() 方法將 id=1 的 tag 綁定(attach)到該 article 上。

不幸的是,我們報錯了,原因就是沒有建立時間。改一下吧。

開啟 Article.php ,找到 tags() 方法,修改成如下:

public function tags(){    return $this->belongsToMany('App\Tag')->withTimestamps();} 

就是這樣。

再執行 attach 命令:

>>> $article = App\Article::first();=> App\Article {#655    id: "1",    user_id: "1",    created_at: "2016-03-20 15:05:18",    updated_at: "2016-03-20 15:05:18",    title: "譚曉龍建立的文章",    body: "真的是",    published_at: "2016-03-28 00:00:00",  }>>> $article->tags()->attach(1);      => null>>> DB::select('select * from article_tag');=> [    {#650      +"article_id": "1",      +"tag_id": "1",      +"created_at": "2016-04-30 14:00:31",      +"updated_at": "2016-04-30 14:00:31",    },  ]>>> $article->tags->toArray();=> [    [      "id" => 1,      "name" => "personal",      "created_at" => "2016-04-30 13:48:49",      "updated_at" => "2016-04-30 13:48:49",      "pivot" => [        "article_id" => "1",        "tag_id" => "1",        "created_at" => "2016-04-30 14:00:31",        "updated_at" => "2016-04-30 14:00:31",      ],    ],  ]>>> $article->toArray();=> [    "id" => 1,    "user_id" => "1",    "created_at" => "2016-03-20 15:05:18",    "updated_at" => "2016-03-20 15:05:18",    "title" => "譚曉龍建立的文章",    "body" => "真的是",    "published_at" => "2016-03-28 00:00:00",    "tags" => [      [        "id" => 1,        "name" => "personal",        "created_at" => "2016-04-30 13:48:49",        "updated_at" => "2016-04-30 13:48:49",        "pivot" => [          "article_id" => "1",          "tag_id" => "1",          "created_at" => "2016-04-30 14:00:31",          "updated_at" => "2016-04-30 14:00:31",        ],      ],    ],  ]>>> $article->tags->lists('name');  => Illuminate\Support\Collection {#653    all: [      "personal",    ],  } 

給文章關聯完之後,我們再給 tag 關聯文章:

>>> $tag=App\Tag::first();=> App\Tag {#666    id: "1",    name: "personal",    created_at: "2016-04-30 13:48:49",    updated_at: "2016-04-30 13:48:49",  }>>> $tag->articles->toArray();=> [    [      "id" => 1,      "user_id" => "1",      "created_at" => "2016-03-20 15:05:18",      "updated_at" => "2016-03-20 15:05:18",      "title" => "譚曉龍建立的文章",      "body" => "真的是",      "published_at" => "2016-03-28 00:00:00",      "pivot" => [        "tag_id" => "1",        "article_id" => "1",      ],    ],  ] 

哈哈,tag 以及你個自動被綁定到了 article ,直接現實了出來。

總結

這就是今天要講的內容,相當於是對 Relationship 的擴充和應用吧。

希望今天的內容你能吸收消化。共勉。

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.