From laraclaude
Detect broken, orphaned, or missing foreign key constraints in Laravel migrations and models.
How this skill is triggered — by the user, by Claude, or both
Slash command
/laraclaude:check-foreign-keys [analyze | fix | fix --dry-run | table-name | fix table-name][analyze | fix | fix --dry-run | table-name | fix table-name]This skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Detect inconsistencies between foreign key constraints defined in migrations and relationships defined in Eloquent models. Finds broken, orphaned, or missing constraints.
Detect inconsistencies between foreign key constraints defined in migrations and relationships defined in Eloquent models. Finds broken, orphaned, or missing constraints.
| Subcommand | Description |
|---|---|
| (no argument) | Analyze all migrations and models, report FK inconsistencies. Read-only. |
fix | Generate missing FK migrations and add missing relationship methods. Asks for confirmation before each change. |
fix --dry-run | Show what migrations and model changes would be generated without writing anything. |
[table-name] | Analyze FK issues involving a specific table (as source or target). |
fix [table-name] | Fix FK issues for a specific table only, with confirmation. |
Glob to find all database/migrations/*.php files.Read and Grep to parse each migration for foreign key definitions:
$table->foreign('column')->references('id')->on('table') -- explicit FK$table->foreignId('table_id')->constrained() -- conventional FK$table->foreignId('column')->constrained('table') -- explicit constrained FK$table->foreignIdFor(Model::class) -- model-based FKonDelete action (cascade, set null, restrict, no action)onUpdate actionGlob to find all app/Models/*.php files.Read to parse each model for:
belongsTo(Model::class, 'foreign_key') -- implies FK on this model's tablehasMany(Model::class, 'foreign_key') -- implies FK on the related model's tablehasOne(Model::class, 'foreign_key') -- implies FK on the related model's tablebelongsToMany(Model::class, 'pivot_table') -- implies FKs on pivot tablemorphTo(), morphMany(), morphOne() -- polymorphic (no FK expected)Check for these categories of problems:
A foreign key constraint exists in a migration, but neither the source model nor the target model defines a corresponding relationship.
Severity: Warning (the FK works at DB level, but there's no Eloquent relationship to use it)
A belongsTo or similar relationship exists in a model, but there's no matching foreign key constraint in any migration.
Severity: Error (data integrity is not enforced at DB level)
A foreign key references a table that is never created in any migration, or is dropped before this FK is created.
Severity: Critical (migration will fail)
A foreign key references a column on the target table that doesn't exist in the target table's CREATE migration.
Severity: Critical (migration will fail)
onDelete('set null') on a column that is NOT NULL -- will cause runtime errorsonDelete('cascade') on a table with soft deletes -- may bypass soft delete logiconDelete specified -- defaults to RESTRICT which may cause unexpected constraint violationsSeverity: Warning
A migration creates a FK referencing a table whose CREATE migration has a later timestamp.
Severity: Critical (migrate:fresh will fail)
The same FK is defined in multiple migrations (e.g., created in one, dropped and re-created in another without the drop).
Severity: Warning
If a [table-name] argument is provided, filter results to only show issues involving that table (as source or target).
Present findings grouped by severity:
CRITICAL ISSUES (will cause failures)
======================================
1. FK references non-existent table
Migration: database/migrations/2025_05_01_create_orders_table.php (line 15)
FK: orders.customer_id -> customers.id
Problem: Table 'customers' is not created in any migration
Fix: Create a migration for the 'customers' table, or fix the reference
WARNING ISSUES (potential problems)
====================================
1. Relationship without FK constraint
Model: App\Models\Order (line 25)
Relationship: belongsTo(Customer::class)
Expected FK: orders.customer_id -> customers.id
Fix: Add foreign key in migration:
$table->foreign('customer_id')->references('id')->on('customers')->onDelete('cascade');
End with a summary:
Category | Count
--------------------------------------|------
Foreign keys in migrations | 45
Relationships in models | 62
Critical issues | 2
Warnings | 8
Tables with no issues | 30
fix or fix [table-name])For each detected issue, generate the appropriate fix with confirmation before applying:
Generate a new migration file that adds the missing foreign key:
Schema::table('orders', function (Blueprint $table) {
$table->foreign('customer_id')->references('id')->on('customers')->onDelete('cascade');
});
Add the missing belongsTo/hasMany/hasOne method to the appropriate model file using Edit.
Suggest renaming migration files to fix timestamp ordering, with confirmation.
Generate a migration to drop and recreate the FK with the correct onDelete action.
Each fix requires explicit user confirmation before applying.
fix --dry-run)Show exactly what migrations would be generated and what model changes would be made, without writing anything. Display the full content of proposed migration files and the model diffs.
morphTo, morphMany, morphOne, morphToMany): These intentionally have no FK constraints. Do not report them as missing FKs. Note them separately as "Polymorphic relationships (no FK expected)".belongsToMany: Check that both FKs exist on the pivot table.belongsTo(Model::class, 'custom_column') uses a non-conventional name, match by the explicit column name.Relation::morphMap() in AppServiceProvider, note this when reporting polymorphic relationships.lc:orphaned-records.npx claudepluginhub edulazaro/laraclaude --plugin laraclaudeDeep analysis of a Laravel Eloquent model - relationships, scopes, casts, fillable, observers, keepers, actions.
Reviews Rails models and migrations for data constraints, foreign keys, referential integrity, race conditions, and orphan risks. Provides checklists, queries, and fix recommendations.
Guides schema design, migration safety, and ORM analysis. Detects database engine and ORM, evaluates normalization and indexing, and validates backward compatibility.