ワンクリックで
laravel-models
Eloquent model patterns and database layer. Use when creating or modifying models, relationships, casts, or observers.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Eloquent model patterns and database layer. Use when creating or modifying models, relationships, casts, or observers.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Form request validation and comprehensive validation testing. Use when creating or modifying form requests, validation rules, or validation tests.
Feature module pattern organizing domain logic into queries, mutations, and actions. Use when implementing data fetching with filters, API mutations with loading states, business logic with UI feedback, or organizing domain-specific code.
File-based routing with page patterns for lists, details, and navigation. Use when creating pages, defining page meta (permissions, layouts), implementing list/detail patterns, or setting up breadcrumbs and headers.
Foundational architecture for Nuxt 4 + Vue 3 + Nuxt UI applications. Use when starting new projects, understanding project structure, or making architectural decisions about directory organization, technology choices, and pattern selection.
Vue component patterns with Composition API and script setup. Use when creating components, understanding script setup order convention, organizing component directories, or implementing component patterns like slideovers, modals, and tables.
Creating custom Vue composables with proper patterns. Use when building reusable stateful logic, shared state management, or encapsulating feature-specific behavior.
| name | laravel-models |
| description | Eloquent model patterns and database layer. Use when creating or modifying models, relationships, casts, or observers. |
Models represent database tables and domain entities.
Related guides:
Models should:
#[UseEloquentBuilder], Laravel 13+ for #[Table], #[ObservedBy], #[UsePolicy], #[UseFactory], etc.)<?php
declare(strict_types=1);
namespace App\Models;
use App\Builders\OrderBuilder;
use App\Enums\OrderStatus;
use Illuminate\Database\Eloquent\Attributes\UseEloquentBuilder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
#[UseEloquentBuilder(OrderBuilder::class)]
class Order extends Model
{
use HasFactory;
protected function casts(): array
{
return [
'status' => OrderStatus::class,
'total' => 'integer',
];
}
// Relationships
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function items(): HasMany
{
return $this->hasMany(OrderItem::class);
}
}
Define casts for type safety:
protected function casts(): array
{
return [
'status' => OrderStatus::class, // Enum
'total' => 'integer', // Integer
'is_paid' => 'boolean', // Boolean
'metadata' => OrderMetadataData::class, // DTO
'completed_at' => 'datetime', // Carbon
'tags' => 'array', // JSON array
];
}
Simple helper methods are acceptable:
class Order extends Model
{
public function isPending(): bool
{
return $this->status === OrderStatus::Pending;
}
public function isCompleted(): bool
{
return $this->status === OrderStatus::Completed;
}
public function canBeCancelled(): bool
{
return $this->isPending() || $this->status === OrderStatus::Processing;
}
}
But NOT business logic:
// ❌ Bad - business logic in model
class Order extends Model
{
public function cancel(): void
{
DB::transaction(function () {
$this->update(['status' => OrderStatus::Cancelled]);
$this->refundPayment();
$this->notifyCustomer();
});
}
}
// ✅ Good - business logic in action
class CancelOrderAction
{
public function __invoke(Order $order): Order
{
return DB::transaction(function () use ($order) {
$order->update(['status' => OrderStatus::Cancelled]);
resolve(RefundPaymentAction::class)($order);
resolve(NotifyCustomerAction::class)($order);
return $order;
});
}
}
For model lifecycle hooks:
<?php
declare(strict_types=1);
namespace App\Observers;
use App\Models\Order;
use Illuminate\Support\Str;
class OrderObserver
{
public function creating(Order $order): void
{
if (! $order->uuid) {
$order->uuid = Str::uuid();
}
}
public function created(Order $order): void
{
// Dispatch event, queue job, etc.
}
public function updating(Order $order): void
{
// Before update
}
public function updated(Order $order): void
{
// After update
}
public function deleted(Order $order): void
{
// After delete
}
}
Register in AppServiceProvider:
use App\Models\Order;
use App\Observers\OrderObserver;
public function boot(): void
{
Order::observe(OrderObserver::class);
}
Extract reusable behavior:
Use in models:
class Order extends Model
{
use HasUuid;
}
// Route
Route::get('/orders/{order}', [OrderController::class, 'show']);
// Controller - automatically receives Order model
public function show(Order $order) { }
Route::get('/orders/{order:uuid}', [OrderController::class, 'show']);
public function resolveRouteBinding($value, $field = null)
{
return $this->where($field ?? 'id', $value)
->where('is_active', true)
->firstOrFail();
}
All models should be unguarded by default.
In your AppServiceProvider::boot() method, call Model::unguard():
<?php
declare(strict_types=1);
namespace App\Providers;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function boot(): void
{
Model::unguard();
}
}
Do NOT use $fillable or $guarded properties on your models:
// ✅ Good - no fillable/guarded
class Order extends Model
{
protected function casts(): array
{
return [
'status' => OrderStatus::class,
];
}
}
// ❌ Bad - don't use fillable
class Order extends Model
{
protected $fillable = ['name', 'email'];
}
// ❌ Bad - don't use guarded
class Order extends Model
{
protected $guarded = [];
}
Important: Always validate input in Form Requests before passing to Actions/Models.
app/Models/
├── Order.php
├── User.php
├── Concerns/
│ ├── HasUuid.php
│ ├── BelongsToTenant.php
│ └── Searchable.php
└── Contracts/
└── Searchable.php
it('can mass assign attributes', function () {
$order = Order::create([
'user_id' => 1,
'status' => 'pending',
'total' => 1000,
'notes' => 'Test order',
]);
expect($order->user_id)->toBe(1)
->and($order->total)->toBe(1000);
});
it('casts status to enum', function () {
$order = Order::factory()->create(['status' => 'pending']);
expect($order->status)->toBeInstanceOf(OrderStatus::class);
});
it('has user relationship', function () {
$order = Order::factory()->create();
expect($order->user)->toBeInstanceOf(User::class);
});