はじめに
Laravelを使っていると、生のSQLを書く機会はほとんどありません。それを実現しているのがEloquent ORMです。テーブルをモデル(クラス)として扱えるため、直感的で読みやすいコードでデータベース操作ができます。
とはいえ、Eloquentが提供するメソッドは非常に多く、where()やget()のような基本的なものだけを使い続けていると、もっと便利な書き方があることに気づかないまま開発を進めてしまいがちです。
この記事では、Eloquentのメソッドを用途別に整理し、実務でよく使う場面を交えながら紹介します。
1. 基本的なデータ取得
// 全件取得(大量データがあるテーブルでは要注意)
$users = User::all();
// 主キーで1件取得
$user = User::find(1);
// 見つからなければ404を自動的に返す
$user = User::findOrFail(1);
// 条件に合う最初の1件
$user = User::where('status', 'active')->first();
// 条件に合う最初の1件、なければ404
$user = User::where('status', 'active')->firstOrFail();
// クエリを実行してコレクションを取得
$users = User::where('age', '>=', 20)->get();
findOrFail()やfirstOrFail()は、コントローラーで毎回if (!$user) abort(404);と書く手間を省いてくれるので、積極的に使っていきたいメソッドです。
2. 絞り込み条件(Where系)
// 基本のWHERE
User::where('age', '>', 18)->get();
// 複数値のいずれかに一致
User::whereIn('id', [1, 2, 3])->get();
User::whereNotIn('id', [1, 2, 3])->get();
// NULL判定
User::whereNull('deleted_at')->get();
User::whereNotNull('email_verified_at')->get();
// 範囲指定
User::whereBetween('price', [1000, 5000])->get();
// 日付・月・年での絞り込み(文字列操作せずに書ける)
User::whereDate('created_at', '2026-07-27')->get();
User::whereMonth('created_at', 7)->get();
User::whereYear('created_at', 2026)->get();
// 同じテーブル内の別カラム同士を比較
Order::whereColumn('shipped_at', '>', 'ordered_at')->get();
日付関連のwhereDate、whereMonth、whereYearは、DATE_FORMATなどをSQLに直接書かなくて済むので地味に便利です。
3. 並び替え・件数制限・ページネーション
// 並び替え
User::orderBy('created_at', 'desc')->get();
// created_atでの並び替えを短く書く
User::latest()->get(); // orderBy('created_at', 'desc') と同じ
User::oldest()->get(); // orderBy('created_at', 'asc') と同じ
// 件数制限
User::take(10)->get();
User::limit(10)->offset(20)->get();
// ページネーション(ページ番号ベース)
$users = User::paginate(15);
// 軽量版(「前へ/次へ」のみ、総ページ数は計算しない)
$users = User::simplePaginate(15);
// カーソルページネーション(大量データに強い)
$users = User::orderBy('id')->cursorPaginate(15);
大量データを扱う一覧画面では、OFFSETが遅くなりがちな通常のpaginate()より、cursorPaginate()のほうがパフォーマンス面で有利になるケースが多いです。
4. 集計・件数チェック
データをアプリ側で数えるのではなく、DB側で集計させるのがポイントです。
User::where('status', 'active')->count();
Order::sum('total_price');
Order::avg('total_price');
Product::max('price');
Product::min('price');
// 存在チェック(count() > 0 より高速)
$exists = User::where('email', $email)->exists();
$notExists = User::where('email', $email)->doesntExist();
count() > 0で存在確認をしているコードを見かけたら、exists()に置き換えるだけでクエリが軽くなります。
5. 作成・更新・削除
// 新規作成($fillable または $guarded の設定が必要)
$user = User::create(['name' => 'Taro', 'email' => 'taro@example.com']);
// あれば取得、なければ作成
$user = User::firstOrCreate(
['email' => 'taro@example.com'],
['name' => 'Taro']
);
// あれば更新、なければ作成
$user = User::updateOrCreate(
['email' => 'taro@example.com'],
['name' => 'Taro Yamada']
);
// 条件に合う複数件を一括更新
User::where('status', 'pending')->update(['status' => 'active']);
// インスタンスの変更を保存
$user->name = 'Jiro';
$user->save();
// 削除
$user->delete();
// 主キー配列から一括削除(find不要)
User::destroy([1, 2, 3]);
// ソフトデリート関連
$user->trashed(); // ソフトデリート済みか判定
$user->restore(); // 復元
$user->forceDelete(); // 完全削除
firstOrCreateとupdateOrCreateは、重複データを作らずに「あれば使う、なければ作る」処理を1行で書けるので、会員登録やインポート処理などでよく使います。
6. リレーション(関連データ)
Eloquentの真価が発揮されるのがリレーション周りです。
// N+1問題を防ぐEager Loading
$posts = Post::with('comments')->get();
// 既に取得済みのモデルに後からリレーションをロード
$post->load('comments');
// リレーションが1件以上存在するものだけ取得
Post::has('comments')->get();
// リレーション先の条件で絞り込み
Post::whereHas('comments', function ($query) {
$query->where('approved', true);
})->get();
// リレーション件数をカラムとして付加
$posts = Post::withCount('comments')->get();
// $posts->first()->comments_count でアクセス可能
with()を使わずにループの中でリレーションにアクセスすると、いわゆる「N+1問題」が発生し、クエリ数が爆発的に増えます。一覧画面やAPIのレスポンスを作るときは、必要なリレーションを先に洗い出してwith()にまとめて渡す習慣をつけると安心です。
7. 大量データ処理・デバッグ系
// 1000件ずつ区切って処理(メモリ節約)
User::chunk(1000, function ($users) {
foreach ($users as $user) {
// 処理
}
});
// LazyCollectionで1件ずつストリーム処理
foreach (User::cursor() as $user) {
// 処理
}
// 取得カラムを絞る(通信量・メモリ削減)
User::select('id', 'name')->get();
// 重複除去
User::select('country')->distinct()->get();
// グループ集計
Order::groupBy('user_id')
->havingRaw('SUM(total_price) > ?', [10000])
->get();
// 実行されるSQLを確認(デバッグ用)
$sql = User::where('status', 'active')->toSql();
数十万件規模のバッチ処理を書くときは、all()やget()でまとめて取得するとメモリ不足になりがちです。chunk()やcursor()を使うことで、メモリを一定に保ちながら安全に処理できます。
まとめ
Eloquentのメソッドは数多くありますが、大きく分けると
- 取得(find, first, get)
- 絞り込み(where系)
- 並び替え・ページネーション
- 集計
- 作成・更新・削除
- リレーション
- 大量データ処理・デバッグ
という7つのカテゴリに整理できます。普段よく使うメソッドだけでなく、firstOrCreateやwhereHas、chunkのような少しマイナーなメソッドも知っておくと、コードの見通しがよくなり、パフォーマンスの落とし穴も避けやすくなります。
ぜひ手元のプロジェクトで、今まで使っていなかったメソッドを一つ試してみてください。