はじめに

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回のみ
}

カスタマイズに関するお問い合わせはこちら