多对多关系也是很常用的一种关系,比如一篇文章可以有多个标签,一个标签下也可以有多篇文章,这就是一个典型的多对多的关系。
1 实现多对多关系
多对多关系我们需要三张表,一张是文章另一张是标签,第三章表是它们的中间表 因为多对多关系需要抽离成两个一对多关系嘛。
1.1 文章结构
public function up()
{
Schema::create('articles', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->text('body');
$table->integer('comment_count')->default(0);
$table->timestamps();
});
}
1.2 标签结构
public function up()
{
Schema::create('tags', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->text('content');
$table->timestamps();
});
}
1.3 中间表结构
public function up()
{
Schema::create('article_tag', function (Blueprint $table) {
$table->increments('id');
$table->integer('article_id');
$table->integer('tag_id');
});
}
2 编写关系
2.1 Article
首先我们看看文章模型中的方法:
public function tags()
{
/**
* (其实 我们只需要写第一个参数就OK了)
* 第二个参数:中间表名 如果不是article_tag的话 必须指定该参数。
* 第三个参数:外键 如果中间表中不是article_id 必须指定该参数。
* 第四个参数:关联到那个外键 如果不是tag_id 必须指定该参数。
*/
return $this->belongsToMany(Tag::class, 'article_tag', 'article_id', 'tag_id');
// return $this->belongsToMany(Tag::class, 'article_tag');
}
然后展示:
Route::get('/', function () {
$article = \App\Article::find(16);
foreach ($article->tags as $tag) {
echo $tag->name . " : " . $tag->content;
echo '<hr />';
}
});
2.2 Tag
Tag模型的编写跟Article模型一模一样。
public function articles()
{
/**
* 可以完全省略后面的参数。
* return $this->belongsToMany(Article::class);
*/
return $this->belongsToMany(Article::class, 'article_tag', 'tag_id', 'article_id');
}
展示:
Route::get('/', function () {
$tag = \App\Tag::find(7);
foreach ($tag->articles as $article) {
echo $article->title . " : " . $article->body;
echo '<hr />';
}
});