欢迎各位兄弟 发布技术文章
这里的技术是共享的
当我们创建一个博客程序的时候,我们当然需要能够撰写博客并发布,另外还要给出一种来关联它们的方法。我们可以使用查找功能,但查找功能留到以后再做,这里先介绍使用标签的方式。比如我们给一篇博客添加了标签“PHP”,那么浏览这篇博客的用户可能会想浏览所有带有该标签的博客,这应该如何实现呢?换句话说,应该如何设计数据库与Eloquent模型呢?这就是这一节所要介绍的多对多关系。
在介绍前可以先复习以下第十四节介绍的《Eloquent关系》,其中介绍了一对一与一对多的关系。
打开 /app/Article.php ,添加多对多关系方法:
public function tags(){
return $this->belongsToMany('App\Tag');
}
然后用命令行创建标签的Eloquent Model:
D:\wamp\www\laravel5>php artisan make:model Tag
Model created successfully.
Created Migration: 2015_07_25_210033_create_tags_table
这条命令会在 /app/ 下生成一个 Tag.php 文件,并且在 /database/migrations/ 下生成一个类似 XXX_create_tags_table.php 的数据库迁移文件,如果没有生成数据库迁移文件的话,可以通过下面的命令行来创建:
D:\wamp\www\laravel5>php artisan make:migration create_tags_table --create=tags
接着修改刚刚生成的数据库迁移文件:
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');
}
接着在命令行下进行数据库迁移:
D:\wamp\www\laravel5>php artisan migrate
Migrated: 2015_07_25_210033_create_tags_table
在 App/Tag.php 中添加多对多关系方法:
public function articles(){
return $this->belongsToMany('App\Article');
}
下面用 php artisan tinker 命令行工具来介绍多对多关系,这样看起来更加清楚。
D:\wamp\www\laravel5>php artisan tinker
Psy Shell v0.4.1 (PHP 5.5.12 ΓÇö cli) by Justin Hileman
>>> $tag = new App\Tag; //创建一个新的tag
=> <App\Tag #000000003d1f1f780000000013a9ed91> {}
>>> $tag->name = 'PHP';
=> "PHP"
>>> $tag->save(); //保存tag
=> true
>>> App\Tag::all()->toArray(); //获取所有 tags
=> [
[
"id" => 1,
"name" => "PHP",
"created_at" => "2015-07-25 21:29:45",
"updated_at" => "2015-07-25 21:29:45"
]
]
>>> App\Tag::lists('name'); //列出所有tags的名称
=> [
"PHP"
]
下面来关联 文章 与 标签:
>>> $article = App\Article::first(); //获取第一篇博客
=> <App\Article #000000003d1f1f6b0000000013a9ed91> {
id: 1,
user_id: 1,
title: "This is the first article",
body: "This is the first article content.",
created_at: "2015-07-25 21:18:08",
updated_at: "2015-07-25 21:18:08",
published_at: "2015-07-25 00:00:00",
excerpt: null
}
>>> $article->tags()->attach(1); // 把 ID 为 1 的tag关联到刚刚获取的博客
=> null
这时查看数据库,发现虽然标签与博客关联上了(有的可能是直接报错,没有添加成功),但是创建时间与修改时间却都是空的。这时需要修改 Article.php 中刚刚添加的 tags() 方法:
public function tags(){
return $this->belongsToMany('App\Tag')->withTimestamps();
}
这时,退出上次的命令行并重新打开(否则刚刚的修改不生效):
D:\wamp\www\laravel5>php artisan tinker
Psy Shell v0.4.1 (PHP 5.5.12 ΓÇö cli) by Justin Hileman
>>> $article = App\Article::first();
=> <App\Article #000000000fac5aa70000000016f5b020> {
id: 1,
user_id: 1,
title: "This is the first article",
body: "This is the first article content.",
created_at: "2015-07-25 21:18:08",
updated_at: "2015-07-25 21:18:08",
published_at: "2015-07-25 00:00:00",
excerpt: null
}
>>> $article->tags()->attach(1);
=> null
这时再次查看数据库,可以看到已经关联成功了。
接着通过命令行来查看多对多关系,获取与给定博客关联的标签:
>>> $article->toArray();
=> [
"id" => 1,
"user_id" => 1,
"title" => "This is the first article",
"body" => "This is the first article content.",
"created_at" => "2015-07-25 21:18:08",
"updated_at" => "2015-07-25 21:18:08",
"published_at" => "2015-07-25 00:00:00",
"excerpt" => null
]
>>> $article->tags->toArray(); //获取博客的所有标签
=> [
[
"id" => 1,
"name" => "PHP",
"created_at" => "2015-07-25 21:29:45",
"updated_at" => "2015-07-25 21:29:45",
"pivot" => [
"article_id" => 1,
"tag_id" => 1,
"created_at" => "2015-07-25 21:38:00",
"updated_at" => "2015-07-25 21:38:00"
]
]
]
>>> $article->toArray(); //已经关联标签的博客数据
=> [
"id" => 1,
"user_id" => 1,
"title" => "This is the first article",
"body" => "This is the first article content.",
"created_at" => "2015-07-25 21:18:08",
"updated_at" => "2015-07-25 21:18:08",
"published_at" => "2015-07-25 00:00:00",
"excerpt" => null,
"tags" => [
[
"id" => 1,
"name" => "PHP",
"created_at" => "2015-07-25 21:29:45",
"updated_at" => "2015-07-25 21:29:45",
"pivot" => [
"article_id" => 1,
"tag_id" => 1,
"created_at" => "2015-07-25 21:38:00",
"updated_at" => "2015-07-25 21:38:00"
]
]
]
]
>>> $article->tags->lists('name'); //列出该博客所有标签的名称
=> [
"PHP"
]
现在进行反向操作,获取与给定标签关联的博客:
>>> $tag = App\Tag::first();
=> <App\Tag #0000000051a0274c0000000008cd8bdd> {
id: 1,
name: "PHP",
created_at: "2015-07-25 21:29:45",
updated_at: "2015-07-25 21:29:45"
}
>>> $tag->articles->toArray();
=> [
[
"id" => 1,
"user_id" => 1,
"title" => "This is the first article",
"body" => "This is the first article content.",
"created_at" => "2015-07-25 21:18:08",
"updated_at" => "2015-07-25 21:18:08",
"published_at" => "2015-07-25 00:00:00",
"excerpt" => null,
"pivot" => [
"tag_id" => 1,
"article_id" => 1
]
]
]
可以看到,也获取成功了。本节完!
该篇属于专题:《Laravel 5 基础视频教程学习笔记》
本文共 2 个回复
dodo 2015/11/12 15:38
我才发现, 除了前2章,其他和 https: // laracasts.com/series/laravel-5-fundamentals 都是一样的....
Specs 2015/11/12 15:47
@ dodo 就是看的那个视频教程啊~
来自 http://9iphp.com/web/laravel/laravel-5-many-to-many-relations.html