eloquent-best-practices — скилл для Claude Code: суть и установка
Скилл задаёт правила работы с Laravel Eloquent: от жадной загрузки связей до защиты от массового заполнения. Помогает писать быстрые выборки без проблемы N+1.
npx skills add iSerter/laravel-claude-agents --skill eloquent-best-practices -a claude-codeЧто делает eloquent-best-practices
Скилл содержит набор паттернов и правил для работы с ORM Eloquent в Laravel. Он учит агента сразу использовать жадную загрузку связей через with(), применять метод withCount() вместо подсчёта в цикле и выбирать только нужные колонки через select(). Это избавляет проект от лишних запросов к базе ещё на этапе генерации кода.
Внутри собраны практические указания для моделей и миграций. Скилл напоминает указывать возвращаемые типы связей (BelongsTo, HasMany), настраивать приведение типов через массив $casts и создавать индексы для внешних ключей. Для обработки объёмных выборок он предписывает использовать chunk() или lazy(), а не выгружать всю таблицу в оперативную память.
Скилл прямо запрещает оставлять пустой массив в protected $guarded = [], потому что это создаёт уязвимость массового заполнения. Чтобы отслеживать забытую жадную загрузку при локальной разработке, автор рекомендует включить Model::preventLazyLoading() внутри AppServiceProvider.
Какие задачи решает
- устранить проблему лишних запросов N+1 через жадную загрузку
- оптимизировать выборки больших объёмов данных через chunk и lazy
- защитить модели Laravel от уязвимостей массового заполнения
- настроить типизацию связей и свойств модели через casts
Примеры запросов агенту
- Проверь этот репозиторий с моделями Laravel на проблему N+1 и оптимизируй запросы.
- Напиши модель Post со связями, типизацией, casts и защитой от массового заполнения.
- Как переписать обновление статусов черновиков сразу на уровне базы данных?
Как установить eloquent-best-practices
1Через Skills CLI (Vercel)
npx skills add iSerter/laravel-claude-agents --skill eloquent-best-practices -a claude-code2Вручную: положить файлы
~/.claude/skills/eloquent-best-practices/SKILL.mdПапка скилла целиком; для одного проекта — .claude/skills/eloquent-best-practices/
1Через Skills CLI (Vercel)
npx skills add iSerter/laravel-claude-agents --skill eloquent-best-practices -a codex2Вручную: положить файлы
.agents/skills/eloquent-best-practices/SKILL.mdДля всех проектов — ~/.agents/skills/
1Через Skills CLI (Vercel)
npx skills add iSerter/laravel-claude-agents --skill eloquent-best-practices -a cursor2Вручную: положить файлы
.cursor/skills/eloquent-best-practices/SKILL.mdCursor читает и .agents/skills/, и .claude/skills/
1GitHub CLI
gh skill install iSerter/laravel-claude-agents eloquent-best-practices2Вручную: положить файлы
.github/skills/eloquent-best-practices/SKILL.md1Через Skills CLI (Vercel)
npx skills add iSerter/laravel-claude-agents --skill eloquent-best-practices -a gemini-cli2Командой платформы
gemini skills install https://github.com/iSerter/laravel-claude-agents --path skills/eloquent-best-practicesВручную: положить файлы
.devin/skills/eloquent-best-practices/SKILL.mdСтарый путь .windsurf/skills/ тоже читается
Через Skills CLI (Vercel)
npx skills add iSerter/laravel-claude-agents --skill eloquent-best-practices -a opencodeClaude.ai
Упакуйте папку в zip и загрузите в Settings → Capabilities → Skills
По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов
Из того же набора2
Похожие
Рядом в теме «Бэкенд и API»
Всё по теме «Бэкенд и API» →Вопросы о eloquent-best-practices
Как установить eloquent-best-practices в Claude Code?
Выполните команду npx skills add iSerter/laravel-claude-agents --skill eloquent-best-practices -a claude-code в терминале. Также можно сохранить файл по пути ~/.claude/skills/eloquent-best-practices/SKILL.md.
Что делает скилл eloquent-best-practices?
Он передаёт агенту свод правил по оптимизации запросов Eloquent, настройке связей, индексации таблиц и безопасной конфигурации моделей в Laravel.
Как скилл предлагает отслеживать lazy loading в разработке?
В коде предлагается вызвать Model::preventLazyLoading(!app()->isProduction()) внутри метода boot() класса AppServiceProvider.
Исходный текст
SKILL.md · MIT
---
name: eloquent-best-practices
description: Best practices for Laravel Eloquent ORM including query optimization, relationship management, and avoiding common pitfalls like N+1 queries.
---
# Eloquent Best Practices
## Query Optimization
### Always Eager Load Relationships
```php
// ❌ N+1 Query Problem
$posts = Post::all();
foreach ($posts as $post) {
echo $post->user->name; // N additional queries
}
// ✅ Eager Loading
$posts = Post::with('user')->get();
foreach ($posts as $post) {
echo $post->user->name; // No additional queries
}
```
### Select Only Needed Columns
```php
// ❌ Fetches all columns
$users = User::all();
// ✅ Only needed columns
$users = User::select(['id', 'name', 'email'])->get();
// ✅ With relationships
$posts = Post::with(['user:id,name'])->select(['id', 'title', 'user_id'])->get();
```
### Use Query Scopes
```php
// ✅ Define reusable query logic
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);
}
}
// Usage
$posts = Post::published()->popular()->get();
```
## Relationship Best Practices
### Define Return Types
```php
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);
}
}
```
### Use withCount for Counts
```php
// ❌ Triggers additional queries
foreach ($posts as $post) {
echo $post->comments()->count();
}
// ✅ Load counts efficiently
$posts = Post::withCount('comments')->get();
foreach ($posts as $post) {
echo $post->comments_count;
}
```
## Mass Assignment Protection
```php
class Post extends Model
{
// ✅ Whitelist fillable attributes
protected $fillable = ['title', 'content', 'status'];
// Or blacklist guarded attributes
protected $guarded = ['id', 'user_id'];
// ❌ Never do this
// protected $guarded = [];
}
```
## Use Casts for Type Safety
```php
class Post extends Model
{
protected $casts = [
'published_at' => 'datetime',
'metadata' => 'array',
'is_featured' => 'boolean',
'views' => 'integer',
];
}
```
## Chunking for Large Datasets
```php
// ✅ Process in chunks to save memory
Post::chunk(200, function ($posts) {
foreach ($posts as $post) {
// Process each post
}
});
// ✅ Or use lazy collections
Post::lazy()->each(function ($post) {
// Process one at a time
});
```
## Database-Level Operations
```php
// ❌ Slow - loads into memory first
$posts = Post::where('status', 'draft')->get();
foreach ($posts as $post) {
$post->update(['status' => 'archived']);
}
// ✅ Fast - single query
Post::where('status', 'draft')->update(['status' => 'archived']);
// ✅ Increment/decrement
Post::where('id', $id)->increment('views');
```
## Use Model Events Wisely
```php
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();
});
}
}
```
## Common Pitfalls to Avoid
### Don't Query in Loops
```php
// ❌ Bad
foreach ($userIds as $id) {
$user = User::find($id);
}
// ✅ Good
$users = User::whereIn('id', $userIds)->get();
```
### Don't Forget Indexes
```php
// Migration
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();
// Composite index for common queries
$table->index(['status', 'published_at']);
});
```
### Prevent Lazy Loading in Development
```php
// In AppServiceProvider boot method
Model::preventLazyLoading(!app()->isProduction());
```
## Checklist
- [ ] Relationships eagerly loaded where needed
- [ ] Only selecting required columns
- [ ] Using query scopes for reusability
- [ ] Mass assignment protection configured
- [ ] Appropriate casts defined
- [ ] Indexes on foreign keys and query columns
- [ ] Using database-level operations when possible
- [ ] Chunking for large datasets
- [ ] Model events used appropriately
- [ ] Lazy loading prevented in development
© iSerter · MIT · iSerter/laravel-claude-agents