We will look at the article and the tags that are attached to the article as an example.
To define this type of relationship, we need three database tables: articles, tags, and intermediate table article_tag. The article_tag table's name must contain the names of the models in alphabetical order and has id models columns.
articles // Articles Table
id - integer
name - string
tags // Tags Table
id - integer
name - string
article_tag // Pivot Table
article_id - integer
tag_id - integer
Now we will define a method through which we can get all the tags for the article using the intermediate table.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
class Article extends Model
{
/**
* The tags that belong to the article.
*/
public function tags() : BelongsToMany
{
return $this->belongsToMany(Tag::class);
}
}
We can also get all articles that contain a certain tag. Let's add a method to the tag model.
public function articles() : BelongsToMany
{
return $this->belongsToMany(Article::class);
}
In addition to naming the intermediate table, you can customize the column names of the keys that connect the two tables by providing extra arguments to the belongsToMany method.
public function tags() : BelongsToMany
{
return $this->belongsToMany(Tag::class, 'article_tag_custom');
}
You may access the article tags using the roles dynamic relationship property
$article = Article::find($id);
foreach ($article->tags as $tag) {
//
}
$tag = Tag::find($id);
foreach ($tag->articles as $article) {
//
}
$tags = Article::find($id)->tags()->orderBy('name')->get();
$articles = Tag::find($id)->articles()->orderBy('updated_at', 'desc')->paginate(10);
You may create a tag model and then use the attach method for creating rows in the intermediate table.
/**
* Tag Attach
*
* @param Article $article
* @param StoreRequest $request
*
* @return void
*/
public function attach(Article $article, StoreRequest $request) : void
{
$tag = Tag::create($request->validated());
$article->tags()->attach($tag->id);
}
To remove the relationship between tag and article, use the detach method.
// Detach a single tag from the article
$article->tags()->detach($tag->id);
// Detach all tags from the article
$article->tags()->detach();
Also, you can use the sync method to remove all relationships between tags and certain article, then add new relationships from the array.
$tagIds = [1, 2, 3];
$article->tags()->sync($tagIds);
You can use the syncWithoutDetaching method if you don't want to detach existing IDs that are missing from the specified array.
$article->tags()->syncWithoutDetaching([$tag->id]);
$tagIds = [1, 2, 3];
$article->tags()->syncWithoutDetaching($tagIds);