Documentation Index
Fetch the complete documentation index at: https://kawax.biz/llms.txt
Use this file to discover all available pages before exploring further.
Eloquent ORMとは
LaravelにはEloquentというオブジェクトリレーショナルマッパー(ORM)が含まれています。
Eloquentはデータベースとの対話を簡単にするためのもので、ActiveRecordパターンを実装しています。
Eloquentを使うと、データベースの各テーブルに対応する「モデル」クラスを用意します。
モデルを通じてレコードの取得・挿入・更新・削除が行えます。
Eloquentを使う前に、config/database.php でデータベース接続を設定してください。
デフォルトでは .env ファイルの DB_* 設定が使われます。
モデルの作成
make:model Artisanコマンドで新しいモデルを生成します。
php artisan make:model Post
マイグレーションと同時に作成する場合は -m オプションを使います。
php artisan make:model Post -m
モデルは app/Models ディレクトリに作成されます。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
// ...
}
モデルとテーブルの対応関係
Eloquentはクラス名からテーブル名を自動的に推測します。
クラス名をスネークケースの複数形に変換したものがテーブル名になります。
| モデル名 | テーブル名 |
|---|
Post | posts |
User | users |
AirTrafficController | air_traffic_controllers |
テーブル名が命名規則に沿わない場合は、モデルに $table プロパティを定義して明示的に指定できます。
class Post extends Model
{
protected $table = 'blog_posts';
}
タイムスタンプ
Eloquentはデフォルトで created_at と updated_at カラムを自動管理します。
マイグレーションで $table->timestamps() を追加しておくと、モデルの保存・更新時に自動的に値がセットされます。
タイムスタンプの自動管理を無効にするには $timestamps を false に設定します。
class Post extends Model
{
public $timestamps = false;
}
マスアサインメント保護
Eloquentでまとめてデータを保存する際は、マスアサインメント保護の設定が必要です。
fillable
代入を許可するカラムを $fillable プロパティで指定します。
class Post extends Model
{
protected $fillable = [
'user_id',
'title',
'body',
'published',
];
}
guarded
逆に代入を禁止するカラムを指定するには $guarded を使います。
class Post extends Model
{
// 主キーのみ保護し、他はすべて許可する
protected $guarded = ['id'];
}
$guarded を空配列にするとすべてのカラムへの代入を許可します。
ユーザー入力をそのまま渡す場合は意図しないカラムが書き換えられる危険があるため、$fillable で許可するカラムを明示的に指定することを推奨します。
Eloquentクエリ実行フロー
User::where()->get() のようなクエリがどのように実行されるか、内部の流れを示します。
基本的なCRUD操作
レコードの取得(Read)
すべてのレコードを取得します。
use App\Models\Post;
$posts = Post::all();
条件を指定して取得します。
// publishedがtrueの投稿を取得
$publishedPosts = Post::where('published', true)->get();
// 最初の1件を取得
$post = Post::where('published', true)->first();
// IDで1件を取得
$post = Post::find(1);
// 見つからない場合は404レスポンスを返す
$post = Post::findOrFail(1);
レコードの作成(Create)
create メソッドでレコードを1つ挿入します($fillable の設定が必要です)。
$post = Post::create([
'title' => 'はじめての投稿',
'body' => 'Laravelは素晴らしいフレームワークです。',
'published' => true,
]);
インスタンスを作成して個別に代入することもできます。
$post = new Post;
$post->title = 'はじめての投稿';
$post->body = 'Laravelは素晴らしいフレームワークです。';
$post->save();
レコードの更新(Update)
モデルを取得して値を変更し、save を呼ぶと更新されます。
$post = Post::find(1);
$post->title = '更新されたタイトル';
$post->save();
update メソッドを使うと、まとめて複数のカラムを更新できます。
Post::find(1)->update([
'title' => '更新されたタイトル',
'published' => true,
]);
条件に一致する複数のレコードをまとめて更新することもできます。
Post::where('published', false)->update(['published' => true]);
レコードの削除(Delete)
delete メソッドでレコードを削除します。
$post = Post::find(1);
$post->delete();
IDを指定して直接削除することもできます。
Post::destroy(1);
// 複数IDをまとめて削除
Post::destroy([1, 2, 3]);
基本的なクエリメソッド
| メソッド | 説明 |
|---|
Post::all() | すべてのレコードを取得 |
Post::find($id) | IDで1件取得(見つからなければ null) |
Post::findOrFail($id) | IDで1件取得(見つからなければ404) |
Post::where('column', 'value')->get() | 条件に一致するレコードを取得 |
Post::where('column', 'value')->first() | 条件に一致する最初の1件を取得 |
Post::where('column', 'value')->count() | 条件に一致する件数を取得 |
Post::orderBy('created_at', 'desc')->get() | 並び順を指定して取得 |
Post::latest()->get() | created_at の降順で取得 |
Post::limit(10)->get() | 件数を絞って取得 |
実践例:Postモデルを使ったデータ操作
マイグレーションで作成した posts テーブルを操作するコントローラーの例です。
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;
class PostController extends Controller
{
// 投稿一覧を表示
public function index(): View
{
$posts = Post::where('published', true)
->latest()
->get();
return view('posts.index', ['posts' => $posts]);
}
// 投稿を作成
public function store(Request $request): RedirectResponse
{
$validated = $request->validate([
'title' => ['required', 'string', 'max:255'],
'body' => ['required', 'string'],
'published' => ['boolean'],
]);
Post::create([
...$validated,
'user_id' => $request->user()->id,
]);
return redirect('/posts');
}
// 投稿を更新
public function update(Request $request, Post $post): RedirectResponse
{
$validated = $request->validate([
'title' => ['required', 'string', 'max:255'],
'body' => ['required', 'string'],
]);
$post->update($validated);
return redirect('/posts');
}
// 投稿を削除
public function destroy(Post $post): RedirectResponse
{
$post->delete();
return redirect('/posts');
}
}
コントローラーのメソッド引数に Post $post と書くと、Laravelがルートパラメーターからモデルを自動的に取得してくれます(ルートモデルバインディング)。
Post::findOrFail($id) を自分で書く必要がなくなります。
モデルイベントのライフサイクル
save() を呼び出したときに発火するイベントの流れを示します。新規作成か更新かで異なるイベントが発火しますが、saving・saved は両方の場合に共通して発火します。
次のステップ
マイグレーション
Eloquentが利用するテーブルをマイグレーションで作成する方法を振り返ります。