はじめに
LaravelのEloquentでは、テーブル間のリレーションを簡単に定義できます。主要なリレーションタイプを紹介します。
1対多 (hasMany / belongsTo)
例:1人のユーザーが複数の投稿を持つ
// User.php
public function posts(): HasMany
{
return $this->hasMany(Post::class);
}
// Post.php
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
// 使用例
$user->posts; // ユーザーの全投稿
$post->user; // 投稿者
$post->user->name; // 投稿者名
多対多 (belongsToMany)
例:投稿とタグ(中間テーブル使用)
// Post.php
public function tags(): BelongsToMany
{
return $this->belongsToMany(Tag::class);
}
// Tag.php
public function posts(): BelongsToMany
{
return $this->belongsToMany(Post::class);
}
// 使用例
$post->tags; // 投稿のタグ一覧
$post->tags()->attach($tagId); // タグを追加
$post->tags()->detach($tagId); // タグを削除
$post->tags()->sync([1, 2, 3]); // タグを同期
1対1 (hasOne / belongsTo)
// User.php
public function profile(): HasOne
{
return $this->hasOne(Profile::class);
}
Eager Loading
N+1問題を回避するため、with()で事前読み込みします。
// NG: N+1問題
$posts = Post::all();
foreach ($posts as $post) {
echo $post->user->name; // 毎回クエリ発行
}
// OK: Eager Loading
$posts = Post::with('user')->get();
foreach ($posts as $post) {
echo $post->user->name; // クエリ1回のみ
}