eloquent-best-practices
Laravel Eloquent ORMのベストプラクティスを提供するスキルで、クエリの最適化やリレーションシップの管理、N+1クエリなどよくある落とし穴の回避方法を網羅します。Eloquentを使った開発で品質とパフォーマンスを向上させたい場面で活躍します。
description の原文を見る
Best practices for Laravel Eloquent ORM including query optimization, relationship management, and avoiding common pitfalls like N+1 queries.
SKILL.md 本文
Eloquent ベストプラクティス
クエリの最適化
常にリレーションシップを Eager Load する
// ❌ N+1 クエリ問題
$posts = Post::all();
foreach ($posts as $post) {
echo $post->user->name; // N個の追加クエリ
}
// ✅ Eager Loading
$posts = Post::with('user')->get();
foreach ($posts as $post) {
echo $post->user->name; // 追加クエリなし
}
必要なカラムのみを選択する
// ❌ すべてのカラムを取得
$users = User::all();
// ✅ 必要なカラムのみ
$users = User::select(['id', 'name', 'email'])->get();
// ✅ リレーションシップ付き
$posts = Post::with(['user:id,name'])->select(['id', 'title', 'user_id'])->get();
クエリスコープを使用する
// ✅ 再利用可能なクエリロジックを定義
class Post extends Model
{
public function scopePublished($query)
{
return $query->where('status', 'published')
->whereNotNull('published_at');
}
public function scopePopular($query, $threshold = 100)
{
return $query->where('views', '>', $threshold);
}
}
// 使用方法
$posts = Post::published()->popular()->get();
リレーションシップのベストプラクティス
戻り値の型を定義する
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Post extends Model
{
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function comments(): HasMany
{
return $this->hasMany(Comment::class);
}
}
withCount でカウントを使用する
// ❌ 追加のクエリを実行
foreach ($posts as $post) {
echo $post->comments()->count();
}
// ✅ 効率的にカウントを読み込む
$posts = Post::withCount('comments')->get();
foreach ($posts as $post) {
echo $post->comments_count;
}
一括割り当て保護
class Post extends Model
{
// ✅ 許可されたアトリビュートをホワイトリスト化
protected $fillable = ['title', 'content', 'status'];
// または保護されたアトリビュートをブラックリスト化
protected $guarded = ['id', 'user_id'];
// ❌ 絶対にこのようなことをしないこと
// protected $guarded = [];
}
型安全性のためにキャストを使用する
class Post extends Model
{
protected $casts = [
'published_at' => 'datetime',
'metadata' => 'array',
'is_featured' => 'boolean',
'views' => 'integer',
];
}
大規模データセットのためのチャンキング
// ✅ チャンク単位で処理してメモリを節約
Post::chunk(200, function ($posts) {
foreach ($posts as $post) {
// 各投稿を処理
}
});
// ✅ またはレイジーコレクションを使用
Post::lazy()->each(function ($post) {
// 一度に1つずつ処理
});
データベースレベルの操作
// ❌ 遅い - 最初にメモリに読み込む
$posts = Post::where('status', 'draft')->get();
foreach ($posts as $post) {
$post->update(['status' => 'archived']);
}
// ✅ 高速 - 単一のクエリ
Post::where('status', 'draft')->update(['status' => 'archived']);
// ✅ インクリメント/デクリメント
Post::where('id', $id)->increment('views');
モデルイベントを賢く使用する
class Post extends Model
{
protected static function booted()
{
static::creating(function ($post) {
$post->slug = Str::slug($post->title);
});
static::deleting(function ($post) {
$post->comments()->delete();
});
}
}
回避すべき一般的な落とし穴
ループ内でクエリしない
// ❌ 悪い
foreach ($userIds as $id) {
$user = User::find($id);
}
// ✅ 良い
$users = User::whereIn('id', $userIds)->get();
インデックスを忘れない
// マイグレーション
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->index();
$table->string('slug')->unique();
$table->string('status')->index();
$table->timestamp('published_at')->nullable()->index();
// 一般的なクエリ用の複合インデックス
$table->index(['status', 'published_at']);
});
開発環境で遅延読み込みを防ぐ
// AppServiceProvider の boot メソッド内
Model::preventLazyLoading(!app()->isProduction());
チェックリスト
- リレーションシップが必要なところで Eager Load されている
- 必要なカラムのみを選択している
- 再利用性のためにクエリスコープを使用している
- 一括割り当て保護が設定されている
- 適切なキャストが定義されている
- 外部キーとクエリカラムにインデックスがある
- 可能な限りデータベースレベルの操作を使用している
- 大規模データセットをチャンキングしている
- モデルイベントが適切に使用されている
- 開発環境で遅延読み込みが防止されている
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- iserter
- ライセンス
- MIT
- 最終更新
- 不明
Source: https://github.com/iserter/laravel-claude-agents / ライセンス: MIT
関連スキル
superfluid
Superfluidプロトコルおよびそのエコシステムに関するナレッジベースです。Superfluidについて情報を検索する際は、ウェブ検索の前にこちらを参照してください。対応キーワード:Superfluid、CFA、GDA、Super App、Super Token、stream、flow rate、real-time balance、pool(member/distributor)、IDA、sentinels、liquidation、TOGA、@sfpro/sdk、semantic money、yellowpaper、whitepaper
civ-finish-quotes
実質的なタスクが真に完了した際に、文明風の儀式的な引用句を追加します。ユーザーやエージェントが機能追加、リファクタリング、分析、設計ドキュメント、プロセス改善、レポート、執筆タスクといった実際の成果物を完成させるときに、明示的な依頼がなくても使用します。短い返信や小さな修正、未完成の作業には適用しません。
nookplot
Base(Ethereum L2)上のAIエージェント向け分散型調整ネットワークです。エージェントがオンチェーンアイデンティティを登録する、コンテンツを公開する、他のエージェントにメッセージを送る、マーケットプレイスで専門家を雇う、バウンティを投稿・請求する、レピュテーションを構築する、共有プロジェクトで協業する、リサーチチャレンジを解くことでNOOKをマイニングする、キュレーションされたナレッジを備えたスタンドアロンオンチェーンエージェントをデプロイする、またはアグリーメントとリワードで収益を得る場合に利用できます。エージェントネットワーク、エージェント調整、分散型エージェント、NOOKトークン、マイニングチャレンジ、ナレッジバンドル、エージェントレピュテーション、エージェントマーケットプレイス、ERC-2771メタトランザクション、Prepare-Sign-Relay、AgentFactory、またはNookplotが言及された場合にトリガーされます。
web3-polymarket
Polygon上でのPolymarket予測市場取引統合です。認証機能(L1 EIP-712、L2 HMAC-SHA256、ビルダーヘッダー)、注文発注(GTC/GTD/FOK/FAK、バッチ、ポストオンリー、ハートビート)、市場データ(Gamma API、Data API、オーダーブック、サブグラフ)、WebSocketストリーミング(市場・ユーザー・スポーツチャネル)、CTF操作(分割、統合、償却、ネガティブリスク)、ブリッジ機能(入金、出金、マルチチェーン)、およびガスレスリレイトランザクションに対応しています。AIエージェント、自動マーケットメーカー、予測市場UI、またはPolygraph上のPolymarketと統合するアプリケーション構築時に活用できます。
ethskills
Ethereum、EVM、またはブロックチェーン関連のリクエストに対応します。スマートコントラクト、dApps、ウォレット、DeFiプロトコルの構築、監査、デプロイ、インタラクションに適用されます。Solidityの開発、コントラクトアドレス、トークン規格(ERC-20、ERC-721、ERC-4626など)、Layer 2ネットワーク(Base、Arbitrum、Optimism、zkSync、Polygon)、Uniswap、Aave、Curveなどのプロトコルとの統合をカバーします。ガスコスト、コントラクトのデシマル設定、オラクルセキュリティ、リエントランシー、MEV、ブリッジング、ウォレット管理、オンチェーンデータの取得、本番環境へのデプロイ、プロトコル進化(EIPライフサイクル、フォーク追跡、今後の変更予定)といったトピックを含みます。
xxyy-trade
このスキルは、ユーザーが「トークン購入」「トークン売却」「トークンスワップ」「暗号資産取引」「取引ステータス確認」「トランザクション照会」「トークンスキャン」「フィード」「チェーン監視」「トークン照会」「トークン詳細」「トークン安全性確認」「ウォレット一覧表示」「マイウォレット」「AIスキャン」「自動スキャン」「ツイートスキャン」「オンボーディング」「IP確認」「IPホワイトリスト」「トークン発行」「自動売却」「損切り」「利益確定」「トレーリングストップ」「保有者」「トップホルダー」「KOLホルダー」などをリクエストした場合、またはSolana/ETH/BSC/BaseチェーンでXXYYを経由した取引について言及した場合に使用します。XXYY Open APIを通じてオンチェーン取引とデータ照会を実現します。