eloquent-best-practices は何をしますか?
Laravel Eloquent ORMに関するベストプラクティス。クエリ最適化、リレーション管理、N+1クエリのような一般的な落とし穴の回避方法を紹介します。
概要
このスキルは、LaravelのEloquent ORMを効果的に使用するためのガイドラインを提供します。以下のトピックをカバーしています:
- クエリ最適化: Eagerローディング、N+1問題の回避、サブクエリの活用
- リレーション管理: 適切なリレーション型の選択、中間テーブルの活用
- パフォーマンス: キャッシュ戦略、グローバルスコープの適用
- コード品質: 命名規則、リポジトリパターンの採用
主なベストプラクティス
1. Eagerローディングの活用
常にN+1クエリを避けるため、withメソッドを使用して関連データを事前にロードします。
// 悪い例
$users = User::all();
foreach ($users as $user) {
echo $user->posts->count(); // N+1問題
}
// 良い例
$users = User::with('posts')->get();
foreach ($users as $user) {
echo $user->posts->count(); // 2クエリのみ
}
2. 適切なリレーション型の選択
hasOne/hasMany: 一対一、一対多belongsTo: 逆の関係belongsToMany: 多対多hasManyThrough: 中間テーブル経由
class User extends Model
{
public function posts(): HasMany
{
return $this->hasMany(Post::class);
}
public function roles(): BelongsToMany
{
return $this->belongsToMany(Role::class);
}
}
3. スコープの使用
クエリの再利用性を高めるためにローカルスコープとグローバルスコープを活用します。
class User extends Model
{
public function scopeActive($query)
{
return $query->where('active', true);
}
public function scopeOfType($query, $type)
{
return $query->where('type', $type);
}
}
// 使用例
$activeAdmins = User::active()->ofType('admin')->get();
4. アクセサとミューテータの活用
属性のフォーマットや変換にはアクセサとミューテータを使用します。
class User extends Model
{
public function getFullNameAttribute(): string
{
return "{$this->first_name} {$this->last_name}";
}
public function setPasswordAttribute(string $value): void
{
$this->attributes['password'] = bcrypt($value);
}
}
5. キャストの活用
属性の型変換には$castsプロパティを使用します。
protected $casts = [
'is_admin' => 'boolean',
'settings' => 'array',
'created_at' => 'datetime:Y-m-d',
];
6. リポジトリパターンの採用(オプション)
複雑なクエリロジックをリポジトリに抽出し、テスト容易性を向上させます。
推奨環境
- Laravel 9以降
- PHP 8.0以降
注意点
- 常にN+1問題に注意し、
withを適切に使用すること - リレーションのネストは必要最低限に留めること
- 大量データの処理にはチャンク(chunk)やカーソル(cursor)を検討すること