Laravel ORM(Eloquent)チートシート
モデル操作の詳細
モデルの定義
class User extends Model
{
// テーブル名の指定(デフォルトはモデル名の複数形)
protected $table = 'users';
// 更新可能なカラム
protected $fillable = ['name', 'email', 'password'];
// 非表示にするカラム(例: JSONシリアライズ時)
protected $hidden = ['password'];
// キャストするデータ型
protected $casts = [
'email_verified_at' => 'datetime',
];
}
データの取得(詳細)
// 全件取得
$users = User::all();
// 条件付き取得(1件だけ)
$user = User::where('email', 'example@example.com')->first();
// 複数のIDで取得(whereIn)
$users = User::whereIn('id', [1, 2, 3])->get();
// 特定のカラムのみ取得(pluck)
$emails = User::pluck('email');
// 一意の値のみ取得(distinct)
$distinctEmails = User::distinct()->pluck('email');
クエリビルダーの詳細
条件付きクエリ
-
where
やその派生系を使って、条件を指定できます。
// 単一条件
$users = User::where('active', 1)->get();
// AND条件
$users = User::where('active', 1)->where('role', 'admin')->get();
// OR条件
$users = User::where('active', 1)->orWhere('role', 'admin')->get();
whereの応用
-
whereIn
: 指定した値のリストの中にあるかをチェック
$users = User::whereIn('id', [1, 2, 3])->get();
-
whereNotIn
: 指定したリストに含まれていないもの
$users = User::whereNotIn('id', [1, 2, 3])->get();
-
whereBetween
: 値が指定範囲にあるかをチェック
$users = User::whereBetween('age', [18, 30])->get();
-
whereNotBetween
: 値が指定範囲外かをチェック
$users = User::whereNotBetween('age', [18, 30])->get();
-
whereNull
/whereNotNull
: カラムがNULLかどうかをチェック
$users = User::whereNull('email_verified_at')->get();
集計関数
// 件数を取得
$count = User::count();
// 最大値
$max = User::max('age');
// 平均
$avg = User::avg('age');
// 合計
$sum = User::sum('points');
クエリの絞り込み
-
limit
とoffset
を使用して、件数やページを制御します。
// 最初の10件を取得
$users = User::limit(10)->get();
// ページング(スキップしたい件数を指定)
$users = User::skip(10)->take(5)->get();
並び替え
// 昇順で並び替え
$users = User::orderBy('name', 'asc')->get();
// 複数条件での並び替え
$users = User::orderBy('age', 'asc')->orderBy('name', 'desc')->get();
リレーションシップの詳細
LaravelのEloquentは、データベースのリレーションシップを簡単に扱うためのメソッドを提供します。以下は、よく使うリレーションの詳細です。
1対多(hasMany)
class User extends Model
{
public function posts()
{
return $this->hasMany(Post::class);
}
}
-
hasMany
は、親モデルに対して複数の子モデルが関連付けられるリレーションです。
// ユーザーの全ての投稿を取得
$user = User::find(1);
$posts = $user->posts;
多対1(belongsTo)
class Post extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
}
-
belongsTo
は、子モデルが親モデルに属していることを示します。
// 投稿の作成者を取得
$post = Post::find(1);
$user = $post->user;
多対多(belongsToMany)
class User extends Model
{
public function roles()
{
return $this->belongsToMany(Role::class);
}
}
-
belongsToMany
は、多対多のリレーションを表し、中間テーブルを使って複数のモデルを結びつけます。
// ユーザーの全ての役割を取得
$user = User::find(1);
$roles = $user->roles;
リレーションのデータ操作
- リレーションを使ってデータを追加・削除・更新することもできます。
// 1対多リレーションに新しい投稿を追加
$user = User::find(1);
$user->posts()->create([
'title' => 'New Post Title',
'content' => 'Post content...'
]);
// 多対多リレーションに役割を追加
$user->roles()->attach($roleId); // 役割を追加
$user->roles()->detach($roleId); // 役割を解除
$user->roles()->sync([1, 2]); // 役割を同期(1,2以外は削除)
ソフトデリートの詳細
ソフトデリートを使用すると、データベースからレコードを物理的に削除するのではなく、「削除済み」とマークして非表示にすることができます。
ソフトデリートの設定
- モデルに
SoftDeletes
トレイトを追加します。
use Illuminate\Database\Eloquent\SoftDeletes;
class User extends Model
{
use SoftDeletes;
// ソフトデリートに使用されるカラム
protected $dates = ['deleted_at'];
}
ソフトデリートの操作
// ソフトデリート(物理的には削除されない)
$user->delete();
// ソフトデリートされたレコードも含む検索
$users = User::withTrashed()->get();
// ソフトデリートされたレコードのみ取得
$trashedUsers = User::onlyTrashed()->get();
// ソフトデリートを取り消す(復元)
$user->restore();
その他の便利な機能
スコープ(クエリの再利用)
- モデルでスコープを定義して、クエリを再利用できます。
// モデル内でスコープを定義
public function scopeActive($query)
{
return $query->where('active', 1);
}
// 使用例
$activeUsers = User::active()->get();
アクセサ(データの整形)
- モデルの属性にアクセスする際に、自動的に整形するメソッドです。
class User extends Model
{
public function getFullNameAttribute()
{
return $this->first_name . ' ' . $this->last_name;
}
}
// 使用例
$user = User::find(1);
echo $user->full_name; // first_name と last_name を結合して表示
ミューテータ(データの保存前に整形)
- モデルの属性を保存する前に、自動的に整形するメソッドです。
class User extends Model
{
public function setPasswordAttribute($value)
{
$this->attributes['password'] = bcrypt($value);
}
}
// 使用例
$user = new User();
$user->password = 'plain-text-password'; // bcryptで自動的にハッシュ化
JOINの詳細
LaravelのEloquentでは、データベースのテーブルを結合(JOIN)することができます。これにより、複数のテーブルからデータを取得することが容易になります。
内部結合(INNER JOIN)
-
join
メソッドを使用して、2つのテーブルを内部結合します。
$users = DB::table('users')
->join('posts', 'users.id', '=', 'posts.user_id')
->select('users.*', 'posts.title')
->get();
この例では、users
テーブルと posts
テーブルを users.id
と posts.user_id
を基準に結合し、両方のテーブルからデータを取得します。
左外部結合(LEFT JOIN)
-
leftJoin
メソッドを使用して、左外部結合を行います。
$users = DB::table('users')
->leftJoin('posts', 'users.id', '=', 'posts.user_id')
->select('users.*', 'posts.title')
->get();
左外部結合では、users
テーブルの全てのデータが取得され、対応する posts
のデータがない場合は NULL
になります。
複数の条件でJOIN
- JOINに複数の条件を指定することも可能です。
$users = DB::table('users')
->join('posts', function ($join) {
$join->on('users.id', '=', 'posts.user_id')
->where('posts.active', '=', 1);
})
->select('users.*', 'posts.title')
->get();
クロス結合(CROSS JOIN)
-
crossJoin
メソッドを使用して、クロス結合(直積)を行います。
$results = DB::table('sizes')
->crossJoin('colors')
->get();
クロス結合では、各サイズと各色のすべての組み合わせが返されます。
高度なJOINの例
- 複数のテーブルを同時にJOINすることもできます。
$users = DB::table('users')
->join('posts', 'users.id', '=', 'posts.user_id')
->join('comments', 'posts.id', '=', 'comments.post_id')
->select('users.name', 'posts.title', 'comments.body')
->get();
この例では、users
、posts
、comments
の3つのテーブルを結合し、それぞれのテーブルからデータを取得します。