Query Builder در مقابل Eloquent — کی کدام را استفاده کنیم؟
«Eloquent کند است» جملهای است که نیمهدرست میشنوم. Eloquent روی Query Builder ساخته شده — کندی از N+1، select * و hydration بیجهت است نه از ORM ذاتاً. با این حال گزارش ۵۰۰هزار ردیفی یا bulk update گاهی DB::table منطقیتر است.
Eloquent چه اضافه میکند؟
- Model instance با cast و accessor
- Relation، event، observer
- Scope و policy integration
Query Builder چه میدهد؟
- سبکتر — stdClass یا array
- کنترل مستقیم join و select
- بدون event model
مثال یکسان — لیست ساده
// Eloquent
Post::published()->with('category')->paginate(15);
// Query Builder
DB::table('posts')
->join('categories', 'categories.id', '=', 'posts.category_id')
->where('posts.status', 'published')
->select('posts.*', 'categories.name as category_name')
->paginate(15);
برای CRUD اپلیکیشن Eloquent خواناتر است.
گزارش aggregate
DB::table('orders')
->selectRaw('DATE(created_at) as day, SUM(total) as revenue')
->where('created_at', '>=', now()->subDays(30))
->groupBy('day')
->orderBy('day')
->get();
نیازی به model hydration نیست.
Bulk update
DB::table('posts')
->where('status', 'draft')
->where('created_at', '<', now()->subYear())
->update(['status' => 'archived']);
Eloquent Model::query()->update() هم میدهد اما event نمیدهد — بدانید چه میخواهید.
chunk و cursor — حافظه
Post::query()->cursor()->each(function (Post $post) {
// پردازش یکی یکی
});
DB::table('logs')->orderBy('id')->chunk(500, function ($rows) {
// ...
});
برای export بزرگ ضروری — بهینهسازی.
ترکیب: Eloquent از DB
$ids = DB::table('post_tag')
->where('tag_id', $tagId)
->pluck('post_id');
Post::whereIn('id', $ids)->with('user')->get();
کی Eloquent؟
CRUD، relation، business app، تست با factory.
کی Query Builder؟
Dashboard آماری، ETL سبک، migration data، admin export سنگین.
Raw SQL
DB::select('SELECT ... WHERE user_id = ?', [$id]);
آخرین راه — binding همیشه.
جمعبندی
پیشفرض Eloquent؛ استثنا Query Builder برای performance مشخص. روابط فقط در Eloquent. Transaction برای هر دو یکسان.