LaravelのEloquent ORMは、テーブル間のリレーションを簡潔に扱えるのが大きな魅力です。この記事では、hasOne、hasMany、belongsToの違いや使い分け方を中心に、リレーションの基本から実践までを解説します。
リレーションとは?Eloquentでの役割
LaravelのEloquent ORMでは、複数のテーブル間に存在する親子関係や紐付けを、モデルクラスにメソッドとして定義することで、直感的にデータの操作が可能になります。たとえば、ユーザーとプロフィール、記事とコメントなどの関係をコードで自然に表現できます。
hasOne:1対1の「親」から見た関係
hasOneは、あるモデルが1つだけ別のモデルを所有する関係を表します。たとえば、ユーザーが1つのプロフィールを持つ場合が該当します。
// Userモデル
public function profile()
{
return $this->hasOne(Profile::class);
}
このように書くことで、$user->profileで対応するプロフィール情報を取得できます。
belongsTo:1対1または多対1の「子」から見た関係
belongsToは、現在のモデルが別のモデルに属していることを示します。たとえば、プロフィールがユーザーに属するというようなケースです。
// Profileモデル
public function user()
{
return $this->belongsTo(User::class);
}
このように記述することで、$profile->userで紐づくユーザー情報を取得できます。
hasMany:1対多の「親」から見た関係
hasManyは、あるモデルが複数の別モデルを所有することを示します。典型的な例は、ユーザーが複数の記事を持つ場合です。
// Userモデル
public function posts()
{
return $this->hasMany(Post::class);
}
このように定義すると、$user->postsでそのユーザーのすべての記事を一覧取得できます。
使い分けの考え方:方向と数の違いに注目
リレーションを定義する際には、「どちらが親か」「関係の数はどうか」を意識することが重要です。
- 親 → 子:hasOne / hasMany
- 子 → 親:belongsTo
この判断基準を覚えるだけでも、迷わずリレーションが設計できます。
リレーションを使ったデータ取得の実践
Eloquentのリレーションは、with()メソッドを使ってあらかじめ関連データを一括取得(Eager Loading)することも可能です。
$users = User::with('profile')->get();
これにより、N+1問題を回避し、パフォーマンスの最適化にもつながります。
複雑なリレーション構造にも対応
Laravelでは、ネストしたリレーション(例:$user->posts->comments)や多対多(belongsToMany)、ポリモーフィックリレーション(morphOne、morphManyなど)にも対応しています。基本の3つをしっかり理解しておくと、複雑な関係もスムーズに設計できます。
まとめ
LaravelのEloquentリレーションは、データベースの設計において非常に強力な機能です。hasOne、hasMany、belongsToの関係を正しく理解し、それぞれの役割と使い分けを身につけることで、アプリケーションの保守性や拡張性が大きく向上します。
これからEloquentを活用した開発を行う方は、まずはこれらの基本リレーションから使いこなしていきましょう。