fix(migrations): drop FK antes que índice al soltar phase_id (MySQL) + idempotencia
- El orden en up() era incorrecto para MySQL: intentaba dropear el índice inspection_templates_phase_id_index antes de la FK que lo sustentaba, dando "Cannot drop index: needed in a foreign key constraint (1553)". Corregido: primero dropForeign, después dropIndex, después dropColumn. - Creación del pivot ahora protegida con Schema::hasTable, para poder reintentar la migración si un fallo previo dejó la tabla creada pero la migración sin marcar como completa. Sin cambios funcionales; suite 91 verde (sqlite). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+18
-11
@@ -15,14 +15,17 @@ return new class extends Migration
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
// Pivot template ↔ project
|
||||
Schema::create('inspection_template_project', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('inspection_template_id')->constrained()->cascadeOnDelete();
|
||||
$table->foreignId('project_id')->constrained()->cascadeOnDelete();
|
||||
$table->timestamps();
|
||||
$table->unique(['inspection_template_id', 'project_id'], 'itp_template_project_unique');
|
||||
});
|
||||
// Pivot template ↔ project (idempotente: si el up() falló a mitad la primera
|
||||
// vez, la tabla puede existir ya; en ese caso saltamos su creación).
|
||||
if (! Schema::hasTable('inspection_template_project')) {
|
||||
Schema::create('inspection_template_project', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('inspection_template_id')->constrained()->cascadeOnDelete();
|
||||
$table->foreignId('project_id')->constrained()->cascadeOnDelete();
|
||||
$table->timestamps();
|
||||
$table->unique(['inspection_template_id', 'project_id'], 'itp_template_project_unique');
|
||||
});
|
||||
}
|
||||
|
||||
// Migrar la asignación existente (project_id en inspection_templates → pivot)
|
||||
$rows = DB::table('inspection_templates')->whereNotNull('project_id')->get(['id', 'project_id']);
|
||||
@@ -37,12 +40,16 @@ return new class extends Migration
|
||||
);
|
||||
}
|
||||
|
||||
// Drop columna phase_id (la asociación a fase deja de existir)
|
||||
// Drop columna phase_id (la asociación a fase deja de existir).
|
||||
// ORDEN IMPORTANTE en MySQL: primero FK, luego índice, luego columna.
|
||||
if (Schema::hasColumn('inspection_templates', 'phase_id')) {
|
||||
Schema::table('inspection_templates', function (Blueprint $table) {
|
||||
// Algunos motores (SQLite) requieren dropear el índice antes de la columna.
|
||||
// 1) FK primero: si no la dropeamos, MySQL rechaza soltar el índice
|
||||
// que la sustenta ("needed in a foreign key constraint").
|
||||
try { $table->dropForeign(['phase_id']); } catch (\Throwable $e) { /* sqlite sin FKs / ya inexistente */ }
|
||||
// 2) Índice después (nombre por convención de Laravel).
|
||||
try { $table->dropIndex('inspection_templates_phase_id_index'); } catch (\Throwable $e) { /* ya no existe */ }
|
||||
try { $table->dropForeign(['phase_id']); } catch (\Throwable $e) { /* sqlite sin FKs */ }
|
||||
// 3) Columna al final.
|
||||
$table->dropColumn('phase_id');
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user