Laravel, just make it work!

Posted on September 2025

See this pile of trash? It's an unfinished website, make it work the way we want but we won't tell you how!

Here's some of the bugs I fixed just recently after inheriting the unfinished "legacy" code base.

//Author 'jesus' (literally found in the code base)


Tale #1: Foreign Key Nightmares and Table Names That Lie

Spent two days chasing a phantom foreign key constraint error. Classic enterprise codebase - no docs, misleading table names, and MySQL throwing tantrums.

The Error That Started It All

Laravel form submission dies with:

SQLSTATE[23000]: Integrity constraint violation: 1452
Cannot add or update a child row: foreign key constraint fails
CONSTRAINT `FK_demande_vehicule_type_vehicule_pl` 
FOREIGN KEY (`id_type_vehicule`) REFERENCES `type_vehicule_pl` (`id`)

Form tries to insert id_type_vehicule = 18. Database says no. ID 18 doesn't exist in type_vehicule_pl.

Down the Rabbit Hole

Frontend shows ID 18 as available. Backend returns ID 18 as valid. Database rejects ID 18. Something's not adding up.

Traced the data flow:

But the constraint points to type_vehicule_pl. Plot twist.

Detective Work: Logging Everything

Added debug logging to see which table the IDs actually belonged to:

foreach(array_unique($vehicule_types) as $type_id) {
    $inCategories = TypeCategorieVehiculePl::where('id', $type_id)->exists();
    $inTypes = TypeVehiculePl::where('id', $type_id)->exists();
    Log::info("ID $type_id - Categories: $inCategories, Types: $inTypes");
}

Results:

The smoking gun. IDs 18-20 exist in categories but not in types.

The Plot Twist: Table Names That Lie

Here's where it gets stupid:

"Table mal nommé, Type_vehicule, = habilitation et pas type de vehicule.."

Translation: The type_vehicule_pl table doesn't contain vehicle types. It contains driver qualifications.

So we have:

The constraint was pointing to the driver qualifications table when it should reference vehicle categories.

Resolution #1

Updated the foreign key to point to the correct table. Two days of debugging solved by understanding what the tables actually contained.


Tale #2: The One-Character Laravel Validation Bug

This week I spent hours debugging what seemed like a JavaScript form submission issue. Turns out it was a one-character typo in a Laravel validation rule.

The Problem

Vehicle request form kept throwing validation errors: "Le champ id_chauffeur.0 sélectionné est invalide"

Translation: "The selected driver field is invalid."

Form had dynamic tables where users could add vehicle types, specific vehicles, and assign drivers. Everything looked fine on the frontend - dropdowns populated, values selected, submit button clicked.

But Laravel kept rejecting the driver selections.

Wrong Turns

Started where most people do: blaming JavaScript.

Added debug logging to see what the form was actually sending:

console.log('=== DEBUGGING CHAUFFEUR VALUES ===')
const chauffeurSelects = document.querySelectorAll('select[name="id_chauffeur[]"]')
console.log('Number of chauffeur dropdowns found:', chauffeurSelects.length)

chauffeurSelects.forEach((select, index) => {
    console.log(`Chauffeur ${index}:`, {
        value: select.value,
        selectedText: select.options[select.selectedIndex]?.text,
        hasValue: !!select.value
    })
})
Plot twist: JavaScript was working perfectly. Found 2 dropdowns, captured values "1" and "3", FormData contained the right entries.

Database Check

Pulled up phpMyAdmin to verify the driver data:

SELECT * FROM chauffeur_pl WHERE id IN (1, 3);

Both drivers existed. Both had archive = 0 (active status). Database was fine.

Frontend working. Database valid. So why was Laravel validation failing?

The Real Culprit

Finally checked the validation rules in app/Http/Requests/DemandePl/Update.php:

$rules['id_chauffeur.*'] = 'required|exists:vehicule_pl,id|numeric';

There it was. The validation rule was checking if driver IDs exist in the vehicle table instead of the driver table.

Copy-paste error. Someone duplicated the vehicle validation rule and forgot to change the table name.

Resolution #2

One line change:

// Before
$rules['id_chauffeur.*'] = 'required|exists:vehicule_pl,id|numeric';

// After  
$rules['id_chauffeur.*'] = 'required|exists:chauffeur_pl,id,archive,0|numeric';

The ,archive,0 part ensures only active drivers are accepted.


Lessons from the Trenches

Pattern Recognition: Both bugs shared the same root cause - misleading naming and poor documentation. Table names that lie, validation rules that check wrong tables, methods that query different tables than their names suggest.

Debug Systematically: Don't blame the frontend first. Follow the data:

  1. Frontend data capture
  2. Backend data processing
  3. Database validation
  4. Framework validation rules

Enterprise Codebase Reality Check:

Framework Complexity: These bugs existed because we had to write validation rules by hand and foreign keys by hand instead of the database just... validating things automatically with proper naming conventions.

Final thought: When you inherit a "legacy" codebase where the previous developer literally signed their work as "jesus", expect miracles to be required just to make basic forms work.

// No enterprise databases were harmed in the making of these debug sessions


Thank you for reading.