当我们创建一个博客程序的时候,我们当然需要能够撰写博客并发布,另外还要给出一种来关联它们的方法。我们可以使用查找功能,但查找功能留到以后再做,这里先介绍使用标签的方式。比如我们给一篇博客添加了标签“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');
- }
注:上面表
article_tag
的表名命名方法为取两个关联表的表名单数形式,然后按首字母升序排序,用下划线 _ 连接。如表 users
与 roles
的中间表可以命名为 role_user
。
接着在命令行下进行数据库迁移:
- 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 基础视频教程学习笔记》
from : http://9iphp.com/web/laravel/laravel-5-many-to-many-relations.html
沒有留言:
張貼留言