AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Laravel Eloquent

skill-dembonauta-skill-doc-generator-laravel-eloquent · by DemboNauta

Guide for working with Laravel Eloquent ORM (Laravel 13.x) — models, queries, relationships, mutators/casting, collections, and API resources.

No reviews yet
0 installs
15 views
0.0% view→install

Install

$ agentstack add skill-dembonauta-skill-doc-generator-laravel-eloquent

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-dembonauta-skill-doc-generator-laravel-eloquent)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
3mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Laravel Eloquent? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Laravel Eloquent ORM (13.x)

Model Generation

php artisan make:model Flight                          # basic model
php artisan make:model Flight -m                       # + migration
php artisan make:model Flight -mfsc                    # + migration, factory, seeder, controller
php artisan make:model Flight -a                       # all: migration, factory, seeder, policy, controller, requests
php artisan make:model Member --pivot                  # pivot model
php artisan model:show Flight                          # inspect attributes & relations

Model Conventions

// Table name: snake_case plural of class (Flight → flights)
// Override with PHP attribute:
#[Table('my_flights')]
class Flight extends Model {}

// Custom primary key
#[Table(key: 'flight_id')]
// Non-incrementing string key
#[Table(key: 'uuid', keyType: 'string', incrementing: false)]

// UUID / ULID keys
class Article extends Model { use HasUuids; }   // UUIDv7 by default
class Article extends Model { use HasUlids; }

// Disable timestamps
#[WithoutTimestamps]
// Custom timestamp column names
public const CREATED_AT = 'creation_date';
public const UPDATED_AT = 'updated_date';

// Custom DB connection
#[Connection('mysql')]

// Default attribute values
protected $attributes = ['delayed' => false, 'options' => '[]'];

Strictness (AppServiceProvider::boot)

Model::preventLazyLoading(! $this->app->isProduction());
Model::preventSilentlyDiscardingAttributes(! $this->app->isProduction());

Retrieving Models

// All records
Flight::all();

// Query builder
$flights = Flight::where('active', 1)->orderBy('name')->limit(10)->get();

// Single record
Flight::find(1);
Flight::findOrFail(1);                    // throws ModelNotFoundException
Flight::where('number', 'FR 900')->first();
Flight::firstOrCreate(['name' => 'London'], ['delayed' => false]);
Flight::firstOrNew(['name' => 'London']);
Flight::updateOrCreate(['departure' => 'Oakland'], ['price' => 99]);

// Aggregates
Flight::where('active', 1)->count();
Flight::max('price');

// Refresh
$fresh = $flight->fresh();    // new instance, does not affect original
$flight->refresh();           // re-hydrates in place, including loaded relations

// Large datasets — avoid memory issues
Flight::chunk(200, function (Collection $flights) { /* ... */ });
Flight::chunkById(200, fn ($flights) => /* ... */, 'id');
Flight::lazy()->each(fn ($flight) => /* ... */);    // lazy collection / cursor

Inserting & Updating

// Create
$flight = new Flight;
$flight->name = 'London';
$flight->save();

// Mass assignment (requires $fillable or $guarded)
protected $fillable = ['name', 'destination'];   // allowlist
protected $guarded  = [];                        // allow all (use carefully)

Flight::create(['name' => 'London', 'destination' => 'Paris']);

// Update
$flight->update(['delayed' => true]);
Flight::where('active', 1)->update(['delayed' => false]);   // mass update

// Upsert
Flight::upsert(
    [['departure' => 'Oakland', 'destination' => 'San Diego', 'price' => 99]],
    ['departure', 'destination'],   // unique columns
    ['price']                       // columns to update on match
);

// Without touching updated_at
Model::withoutTimestamps(fn () => $post->increment('reads'));

Deleting Models

$flight->delete();
Flight::destroy([1, 2, 3]);
Flight::where('active', 0)->delete();

// Soft deletes — add SoftDeletes trait + deleted_at column in migration
use Illuminate\Database\Eloquent\SoftDeletes;
class Flight extends Model { use SoftDeletes; }

$flight->trashed();                 // bool
Flight::withTrashed()->get();
Flight::onlyTrashed()->get();
$flight->restore();
$flight->forceDelete();

// Pruning — add Prunable/MassPrunable trait, define prunable() query, schedule
php artisan model:prune --pretend

Query Scopes

// Global scope (applies to all queries on model)
protected static function booted(): void
{
    static::addGlobalScope('active', fn (Builder $builder) => $builder->where('active', 1));
}

// Remove global scope
Flight::withoutGlobalScope('active')->get();

// Local scope
public function scopeActive(Builder $query): void
{
    $query->where('active', 1);
}
// Usage:
Flight::active()->orderBy('name')->get();

// Pending attributes scope (sets attributes on model when scope applied)
public function scopeForCurrentUser(Builder $query): Builder
{
    return $query->where('user_id', Auth::id())->withPendingAttributes(['user_id' => Auth::id()]);
}

Relationships

Defining

// One to One
public function phone(): HasOne
{
    return $this->hasOne(Phone::class);           // FK: user_id on phones
}

// Inverse
public function user(): BelongsTo
{
    return $this->belongsTo(User::class);
}

// One to Many
public function comments(): HasMany
{
    return $this->hasMany(Comment::class)->chaperone(); // auto-hydrate parent
}

// Many to Many
public function roles(): BelongsToMany
{
    return $this->belongsToMany(Role::class);
}
// Access pivot: $user->roles->first()->pivot->created_at

// Has One of Many
public function latestOrder(): HasOne
{
    return $this->hasOne(Order::class)->latestOfMany();
}
public function largestOrder(): HasOne
{
    return $this->hasOne(Order::class)->ofMany('price', 'max');
}

// Has One / Has Many Through
public function mechanic(): HasOneThrough
{
    return $this->hasOneThrough(Owner::class, Car::class);
}

// Polymorphic
public function comments(): MorphMany
{
    return $this->morphMany(Comment::class, 'commentable');
}

// Default model (Null Object pattern)
public function user(): BelongsTo
{
    return $this->belongsTo(User::class)->withDefault(['name' => 'Guest']);
}

Querying

// Eager loading — prevents N+1
Post::with('comments')->get();
Post::with(['comments', 'author'])->get();
Post::with('comments.author')->get();          // nested

// Constrained eager load
Post::with(['comments' => fn ($q) => $q->where('active', 1)])->get();

// Lazy eager load (after retrieval)
$posts->load('comments');
$posts->loadMissing('comments');

// Existence / absence
Post::has('comments')->get();
Post::has('comments', '>=', 3)->get();
Post::whereHas('comments', fn ($q) => $q->where('content', 'like', '%code%'))->get();
Post::doesntHave('comments')->get();

// Aggregate on relation
Post::withCount('comments')->get();             // $post->comments_count
Post::withMin('price', 'amount')->get();

// whereBelongsTo
Post::whereBelongsTo($user)->get();
Post::whereBelongsTo($user, 'author')->get();   // custom relationship name

Accessors, Mutators & Casting

// Accessor + Mutator (Attribute class)
protected function firstName(): Attribute
{
    return Attribute::make(
        get: fn (string $value) => ucfirst($value),
        set: fn (string $value) => strtolower($value),
    );
}

// Cast via casts() method
protected function casts(): array
{
    return [
        'is_admin'   => 'boolean',
        'options'    => 'array',          // JSON ↔ PHP array
        'options'    => AsCollection::class,
        'options'    => AsArrayObject::class,
        'birthday'   => 'date',
        'created_at' => 'datetime:Y-m-d',
        'role'       => UserRole::class,  // PHP enum cast
        'secret'     => 'encrypted',
    ];
}

Collections

Eloquent collections extend Laravel's base Collection with extra model-specific methods:

$users->find(1);
$users->findOrFail(1);
$users->fresh();                        // re-fetch all from DB
$users->load(['comments', 'posts']);    // eager load on collection
$users->loadMissing('comments');
$users->modelKeys();                    // [1, 2, 3, ...]
$users->only([1, 2, 3]);
$users->except([4, 5]);
$users->makeVisible(['phone']);
$users->makeHidden(['password']);
$users->toQuery()->update(['status' => 'active']); // bulk update
$users->unique();

// Custom collection
#[CollectedBy(UserCollection::class)]
class User extends Model {}

API Resources

php artisan make:resource UserResource
php artisan make:resource UserCollection   # resource collection
// Single resource
class UserResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        return [
            'id'         => $this->id,
            'name'       => $this->name,
            'email'      => $this->email,
            'posts'      => PostResource::collection($this->posts),
            'created_at' => $this->created_at,
        ];
    }
}

// Return from route/controller
return new UserResource(User::findOrFail($id));
return User::findOrFail($id)->toResource();          // convention-based
return UserResource::collection(User::all());
return User::all()->toResourceCollection();          // convention-based

// Disable data wrapping (in AppServiceProvider::boot)
JsonResource::withoutWrapping();

// Conditional attributes
'secret' => $this->when(Auth::user()->isAdmin(), $this->secret),
'posts'  => PostResource::collection($this->whenLoaded('posts')),

Events & Observers

// Model events: retrieved, creating, created, updating, updated,
//               saving, saved, deleting, deleted, restoring, restored

// Observer class
php artisan make:observer UserObserver --model=User

class UserObserver
{
    public function created(User $user): void { /* ... */ }
    public function updated(User $user): void { /* ... */ }
}

// Register in AppServiceProvider::boot
User::observe(UserObserver::class);

// Mute events temporarily
User::withoutEvents(fn () => User::factory()->create());

Quick Reference

| Task | Method | |------|--------| | Find or 404 | Model::findOrFail($id) | | First or create | Model::firstOrCreate(['key' => $val], $extra) | | Upsert | Model::upsert($data, $unique, $update) | | Soft delete restore | $model->restore() | | Force delete | $model->forceDelete() | | Eager load | Model::with('relation')->get() | | Prevent N+1 | Model::preventLazyLoading(true) | | Chunk large sets | Model::chunk(200, fn($rows) => ...) | | Mass update | Model::where(...)->update([...]) | | Scope | public function scopeName(Builder $q) | | JSON cast | 'column' => 'array' in casts() | | API resource | return new UserResource($model) |

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.