Laravel中利用中间表处理多对多的关系

2017/3/15 posted in  LARAVEL

今天谈谈Laravel中非常有用但是又非常难以理解的特性:中间表

拿博客和博客的标签举例:一个博客有多个标签,形成了多对多的关系,使用中间表来表示这种关系,数据库结构设计如下:

博文表:blog

– id
– title
- content

标签表:tag

- id
- name

博文和标签的关联表:blog_tag

- blog_id
- tag_id

然后我们在模型中使用BelongsToMany()来使用中间表表示博文和标签关系
博文模型app/Blog.php:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Blog extends Model
{
    protected $table = 'blog';
    public $timestamps = false;

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

标签模型app/Tag.php:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Tag extends Model
{
    protected $table = 'tag';
    public $timestamps = false;

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

我们可以进一步指定中间表的表名和关联的字段:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Blog extends Model
{
    //
    protected $table = 'blog';
    public $timestamps = false;

    public function tag()
    {
        return $this->belongsToMany('App\Tag', 'blog_tag', 'blog_id', 'tag_id');
    }
}

博文新关联一个标签

$blog = Blog::find($blogId);
$blog->tag()->attach($tagId);// $tagId就是需要关联的标签的id

博文删除关联的一个标签

$blog = Blog::find($blogId);
$blog->tag()->detach($tagId);// $tagId就是需要删除的关联的标签的id

删除所有与标签的关联

$blog = Blog::find($blogId);
$blog->tag()->detach();

注意:attach和detach的参数都可以是一个数组,表示添加或者删除多个关联的标签。

博文使用新的标签关联替换原有的关联:

$blog->tag()->sync([1, 2, 3]);

参考资料

Pivot tables and many-to-many relationships