Laravel eloquent
Skill fusengine/agents/plugins/laravel-expert/skills/laravel-eloquent
Complete Eloquent ORM for Laravel 13 - PHP Attributes (#[Table], #[Fillable], #[Casts]), models, relationships, queries, observers, factories. Use when working with database models.From its SKILL.md
npx -y skills add fusengine/agents --skill laravel-eloquentAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 22 stars22 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
6.8 KB, ~1.4k tokens by cl100k_base, as published. Nobody here has run it
Laravel Eloquent ORM (L13 — Attributes-first)
Agent Workflow (MANDATORY)
Before ANY implementation, use TeamCreate to spawn 3 agents:
- fuse-ai-pilot:explore-codebase - Inspect existing models, mixed property/attribute usage
- fuse-ai-pilot:research-expert - Verify Laravel 13 Eloquent + Attributes docs via Context7
- mcp__context7__query-docs - Query attribute patterns (#[Fillable], #[Casts], #[Scope])
After implementation, run fuse-ai-pilot:sniper for validation.
Overview
Laravel 13 promotes PHP 8.3 Attributes as the primary metadata mechanism on Eloquent models. Legacy properties ($fillable, $hidden, ...) remain supported for backward compatibility but should not be mixed with their attribute counterparts.
| Feature | Attribute (L13 MAIN) | Legacy property |
|---|---|---|
| Table name | #[Table('users')] | protected $table |
| Mass assignment | #[Fillable([...])] | protected $fillable |
| Hidden / Visible | #[Hidden([...])] / #[Visible([...])] | protected $hidden / $visible |
| Guarded | #[Guarded([...])] / #[Unguarded] | protected $guarded |
| Casts | #[Casts([...])] | casts() method |
| Appends | #[Appends([...])] | protected $appends |
| Touches | #[Touches([...])] | protected $touches |
| Connection | #[Connection('mysql')] | protected $connection |
Critical Rules
- Attributes are the source of truth - Use
#[Fillable],#[Casts],#[Hidden]on new code - Never mix attribute + property for the same concern (
#[Fillable]AND$fillable) - Eager load relationships - Prevent N+1 queries with
with() - No
new Model()inboot()- ThrowsLogicExceptionin L13 (booted lifecycle protected) - Use factories in tests - Never hardcode test data
Architecture
app/Models/
├── User.php # #[Table], #[Fillable], #[Hidden], #[Casts]
├── Post.php # #[Connection], #[Appends], relationships
└── Concerns/
└── HasUuid.php # Reusable trait
→ See templates/ModelBasic.php.md
Reference Guide
Concepts
- Migration L12→L13: legacy-properties.md
- Modeling: models.md · casts.md · accessors-mutators.md · serialization.md · soft-deletes.md
- Relationships: relationships-basic.md · relationships-many-to-many.md · relationships-advanced.md · relationships-polymorphic.md
- Querying: eager-loading.md · scopes.md · aggregates.md · pagination.md · batch-operations.md · query-debugging.md
- Lifecycle / Output: events-observers.md · collections.md · resources.md · factories.md · transactions.md · performance.md
Templates
| Template | When to Use |
|---|---|
| ModelBasic.php.md | Attribute-based model |
| ModelRelationships.php.md | All relationship types |
| ModelCasts.php.md | #[Casts] and accessors |
| Observer.php.md | Complete observer |
| Factory.php.md | Factory with states |
| Resource.php.md | API resource |
| EagerLoadingExamples.php.md | N+1 prevention |
Quick Reference
Attribute-based Model (L13 MAIN)
use Illuminate\Database\Eloquent\Attributes\{Table, Fillable, Hidden, Casts};
use Illuminate\Database\Eloquent\Model;
#[Table('users')]
#[Fillable(['name', 'email', 'password'])]
#[Hidden(['password', 'remember_token'])]
#[Casts(['email_verified_at' => 'datetime', 'is_admin' => 'boolean'])]
final class User extends Model
{
public function posts(): HasMany
{
return $this->hasMany(Post::class);
}
}
Scope (attribute syntax)
#[Scope]
protected function published(Builder $query): void
{
$query->whereNotNull('published_at');
}
// Usage: Post::published()->get();
Eager Loading
$posts = Post::with('author')->get(); // 2 queries, not N+1
→ Legacy $fillable / $hidden style — see legacy-properties.md
Best Practices
DO
- Declare metadata with PHP Attributes (
#[Table],#[Fillable],#[Casts], ...) - Use
finalon model classes when not extended - Eager load with
with() - Use factories in tests
- Cast dates, arrays, enums via
#[Casts]
DON'T
- Mix
#[Fillable]and$fillableon the same model (conflict — single source of truth) - Instantiate models in
boot()/booted()— L13 throwsLogicException - Lazy-load relationships in loops (N+1)
- Use
#[Unguarded]in production - Query inside accessors / mutators
- Put business logic in models (use Services/Actions)
What ships with it: 29 files
124.3 KB alongside SKILL.md
references/
- accessors-mutators.md2.8 KB
- aggregates.md3.2 KB
- batch-operations.md3.3 KB
- casts.md3.2 KB
- collections.md3.2 KB
- eager-loading.md3.2 KB
- events-observers.md3.2 KB
- factories.md3.2 KB
- legacy-properties.md3.4 KB
- models.md2.7 KB
- pagination.md2.8 KB
- performance.md3.4 KB
- query-debugging.md2.8 KB
- relationships-advanced.md3.0 KB
- relationships-basic.md2.8 KB
- relationships-many-to-many.md3.2 KB
- relationships-polymorphic.md3.3 KB
- resources.md3.2 KB
- scopes.md2.7 KB
- serialization.md3.4 KB
- soft-deletes.md2.9 KB
- templates/EagerLoadingExamples.php.md7.7 KB
- templates/Factory.php.md9.1 KB
- templates/ModelBasic.php.md6.4 KB
- templates/ModelCasts.php.md8.3 KB
- templates/ModelRelationships.php.md8.1 KB
- templates/Observer.php.md8.4 KB
- templates/Resource.php.md9.0 KB
- transactions.md2.7 KB