股票场内基金交易,没时间盯盘?
多对多关系的 tag 事例
前言
上一节,我们对 flash message 的使用做一个讲解,了解到什么是 flash message,而且会进行简单的使用。本节,我们对数据库表多对多的形式进行讲解,并以文章 tags 作例子。
说明
开发环境:Windows 7
Laravel 版本: 5+
IDE: Phpstorm
数据库在,之前我们就对 Laravel 的 Eloquent 和 Migration 做过两节介绍,而且在 Relationships 讲过数据表之间的外键关系,那也是基本的一对多。
本节我们对数据库中的多对多进行一个讲解,而且所举的例子就是 tags ,文章标签。
现在咱们博客的基本功能已经有了,写文章,发表文章等。但是随着文章越来越多,文章的筛选和管理就成了问题,要是能有 tag 标记每篇文章的关键词,这对文章的管理将是一个很大的改善。
下面我们就来看一下 Eloquent 是怎么实现给文章 tagging 的。
打开的 Article.php ,还记得当初我们为每篇文章(Article)关联作者(User)是在哪个方法吗?算了,你也回答不了,就在最下面的 user() 方法,里面写了一句 belongsTo 就指明了文章所属。该语句与 hasMany 是相对的,文章只能 belongsTo 一个作者,但是一名作者可以 hasMany 文章,就是这么个关系。
但是在 tag 这里,belongsTo 和 hasMany 就有点讲不通了,一篇文章不能只 belongsTo 一个 tag ,应该是 belongsToMany tags 才通顺。
所在在 user() 方法下面再价一个 tags() 方法,如下所示:
1 2 3 4 |
public function tags(){ return $this->belongsToMany('App\Tag'); } |
下面呢,我们去创建一个 Tag Eloquent model吧。
创建 Tag model类和 Tag 表
在命令行下输入命令:php artisan make:model Tag。
再在命令行下输入命令: php artisan make:migration createtagtable –create=tags
打开这个 createtagtable.php ,在这里创建 tag 表的一些属性或者说列:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
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 的方法:
1 2 3 4 |
public function articles(){ return $this->belongsToMany('App\Article'); | } |
保存后,打开命令行,通过 tinker 来验证是否成功:php artisan tinker
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
>>> $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 模式下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
>>> 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\QueryException with message '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() 方法,修改成如下:
1 2 3 4 |
public function tags(){ return $this->belongsToMany('App\Tag')->withTimestamps(); } |
就是这样。
再执行 attach 命令:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
>>> $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 关联文章:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
>>> $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 元限制的证券账户吗?

如果您想去掉最低交易佣金 5 元限制,使用微信扫描左边小程序二维码,访问微信小程序「优财助手」,点击底部菜单「福利」,阅读文章「通过优财开证券账户无最低交易佣金 5 元限制」,按照文章步骤操作即可获得免 5 元证券账户,股票基金交易手续费率万 2.5。
请注意,一定要按照文章描述严格操作,如错误开户是无法获得免 5 元证券账户的。