欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

[Laravel 5 教程学习笔记] 十九、多对多关系-标签 有大用

shiping1 的头像

当我们创建一个博客程序的时候,我们当然需要能够撰写博客并发布,另外还要给出一种来关联它们的方法。我们可以使用查找功能,但查找功能留到以后再做,这里先介绍使用标签的方式。比如我们给一篇博客添加了标签“PHP”,那么浏览这篇博客的用户可能会想浏览所有带有该标签的博客,这应该如何实现呢?换句话说,应该如何设计数据库与Eloquent模型呢?这就是这一节所要介绍的多对多关系。

 

在介绍前可以先复习以下第十四节介绍的《Eloquent关系》,其中介绍了一对一与一对多的关系。

打开 /app/Article.php ,添加多对多关系方法:


  1. public function tags(){

  2. return $this->belongsToMany('App\Tag');

  3. }

然后用命令行创建标签的Eloquent Model:


  1. D:\wamp\www\laravel5>php artisan make:model Tag

  2. Model created successfully.

  3. Created Migration: 2015_07_25_210033_create_tags_table

这条命令会在 /app/ 下生成一个 Tag.php 文件,并且在 /database/migrations/ 下生成一个类似 XXX_create_tags_table.php 的数据库迁移文件,如果没有生成数据库迁移文件的话,可以通过下面的命令行来创建:


  1. D:\wamp\www\laravel5>php artisan make:migration create_tags_table --create=tags

接着修改刚刚生成的数据库迁移文件:


  1. public function up()

  2. {

  3. Schema::create('tags', function(Blueprint $table)

  4. {

  5. $table->increments('id');

  6. $table->string('name');

  7. $table->timestamps();

  8. });

  9.  

  10. Schema::create('article_tag', function(Blueprint $table){

  11. $table->integer('article_id')->unsigned()->index();

  12. $table->foreign('article_id')->references('id')->on('articles')->onDelete('cascade');

  13.  

  14. $table->integer('tag_id')->unsigned()->index();

  15. $table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade');

  16.  

  17. $table->timestamps();

  18.  

  19. });

  20. }

  21.  

  22.  

  23. public function down()

  24. {

  25. Schema::drop('tags');

  26. Schema::drop('article_tag');

  27. }

注:上面表 article_tag 的表名命名方法为取两个关联表的表名单数形式,然后按首字母升序排序,用下划线 _ 连接。如表 users 与 roles 的中间表可以命名为 role_user 。

接着在命令行下进行数据库迁移:


  1. D:\wamp\www\laravel5>php artisan migrate

  2. Migrated: 2015_07_25_210033_create_tags_table

在 App/Tag.php 中添加多对多关系方法:


  1. public function articles(){

  2. return $this->belongsToMany('App\Article');

  3. }

下面用 php artisan tinker 命令行工具来介绍多对多关系,这样看起来更加清楚。


  1. D:\wamp\www\laravel5>php artisan tinker

  2. Psy Shell v0.4.1 (PHP 5.5.12 ΓÇö cli) by Justin Hileman

  3. >>> $tag = new App\Tag; //创建一个新的tag

  4. => <App\Tag #000000003d1f1f780000000013a9ed91> {}

  5. >>> $tag->name = 'PHP';

  6. => "PHP"

  7. >>> $tag->save(); //保存tag

  8. => true

  9. >>> App\Tag::all()->toArray(); //获取所有 tags

  10. => [

  11. [

  12. "id" => 1,

  13. "name" => "PHP",

  14. "created_at" => "2015-07-25 21:29:45",

  15. "updated_at" => "2015-07-25 21:29:45"

  16. ]

  17. ]

  18. >>> App\Tag::lists('name'); //列出所有tags的名称

  19. => [

  20. "PHP"

  21. ]

下面来关联 文章 与 标签:


  1. >>> $article = App\Article::first(); //获取第一篇博客

  2. => <App\Article #000000003d1f1f6b0000000013a9ed91> {

  3. id: 1,

  4. user_id: 1,

  5. title: "This is the first article",

  6. body: "This is the first article content.",

  7. created_at: "2015-07-25 21:18:08",

  8. updated_at: "2015-07-25 21:18:08",

  9. published_at: "2015-07-25 00:00:00",

  10. excerpt: null

  11. }

  12. >>> $article->tags()->attach(1); // 把 ID 为 1 的tag关联到刚刚获取的博客

  13. => null

这时查看数据库,发现虽然标签与博客关联上了(有的可能是直接报错,没有添加成功),但是创建时间与修改时间却都是空的。这时需要修改 Article.php 中刚刚添加的 tags() 方法:


  1. public function tags(){

  2. return $this->belongsToMany('App\Tag')->withTimestamps();

  3. }

这时,退出上次的命令行并重新打开(否则刚刚的修改不生效):


  1. D:\wamp\www\laravel5>php artisan tinker

  2. Psy Shell v0.4.1 (PHP 5.5.12 ΓÇö cli) by Justin Hileman

  3. >>> $article = App\Article::first();

  4. => <App\Article #000000000fac5aa70000000016f5b020> {

  5. id: 1,

  6. user_id: 1,

  7. title: "This is the first article",

  8. body: "This is the first article content.",

  9. created_at: "2015-07-25 21:18:08",

  10. updated_at: "2015-07-25 21:18:08",

  11. published_at: "2015-07-25 00:00:00",

  12. excerpt: null

  13. }

  14. >>> $article->tags()->attach(1);

  15. => null

这时再次查看数据库,可以看到已经关联成功了。

laravel-many-to-many

接着通过命令行来查看多对多关系,获取与给定博客关联的标签:


  1. >>> $article->toArray();

  2. => [

  3. "id" => 1,

  4. "user_id" => 1,

  5. "title" => "This is the first article",

  6. "body" => "This is the first article content.",

  7. "created_at" => "2015-07-25 21:18:08",

  8. "updated_at" => "2015-07-25 21:18:08",

  9. "published_at" => "2015-07-25 00:00:00",

  10. "excerpt" => null

  11. ]

  12. >>> $article->tags->toArray(); //获取博客的所有标签

  13. => [

  14. [

  15. "id" => 1,

  16. "name" => "PHP",

  17. "created_at" => "2015-07-25 21:29:45",

  18. "updated_at" => "2015-07-25 21:29:45",

  19. "pivot" => [

  20. "article_id" => 1,

  21. "tag_id" => 1,

  22. "created_at" => "2015-07-25 21:38:00",

  23. "updated_at" => "2015-07-25 21:38:00"

  24. ]

  25. ]

  26. ]

  27. >>> $article->toArray(); //已经关联标签的博客数据

  28. => [

  29. "id" => 1,

  30. "user_id" => 1,

  31. "title" => "This is the first article",

  32. "body" => "This is the first article content.",

  33. "created_at" => "2015-07-25 21:18:08",

  34. "updated_at" => "2015-07-25 21:18:08",

  35. "published_at" => "2015-07-25 00:00:00",

  36. "excerpt" => null,

  37. "tags" => [

  38. [

  39. "id" => 1,

  40. "name" => "PHP",

  41. "created_at" => "2015-07-25 21:29:45",

  42. "updated_at" => "2015-07-25 21:29:45",

  43. "pivot" => [

  44. "article_id" => 1,

  45. "tag_id" => 1,

  46. "created_at" => "2015-07-25 21:38:00",

  47. "updated_at" => "2015-07-25 21:38:00"

  48. ]

  49. ]

  50. ]

  51. ]

  52. >>> $article->tags->lists('name'); //列出该博客所有标签的名称

  53. => [

  54. "PHP"

  55. ]

现在进行反向操作,获取与给定标签关联的博客:


  1. >>> $tag = App\Tag::first();

  2. => <App\Tag #0000000051a0274c0000000008cd8bdd> {

  3. id: 1,

  4. name: "PHP",

  5. created_at: "2015-07-25 21:29:45",

  6. updated_at: "2015-07-25 21:29:45"

  7. }

  8. >>> $tag->articles->toArray();

  9. => [

  10. [

  11. "id" => 1,

  12. "user_id" => 1,

  13. "title" => "This is the first article",

  14. "body" => "This is the first article content.",

  15. "created_at" => "2015-07-25 21:18:08",

  16. "updated_at" => "2015-07-25 21:18:08",

  17. "published_at" => "2015-07-25 00:00:00",

  18. "excerpt" => null,

  19. "pivot" => [

  20. "tag_id" => 1,

  21. "article_id" => 1

  22. ]

  23. ]

  24. ]

可以看到,也获取成功了。本节完!


 
 
转载请注明来源:[Laravel 5 教程学习笔记] 十九、多对多关系-标签 - Specs' Blog-就爱PHP

本文共 2 个回复


普通分类: