How to fix the 'Identifier name too long' exception in your Laravel migrations
Do you love verbosity in your database tables and columns? ✅
Are you running into issues where Laravel’s migration helpers like foreignIdFor()
are not letting your migrations run? ❗
Take for instance this migration:
use App\Models\KnowledgeBaseResource;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('company_knowledge_base_resource_matches', function (Blueprint $table) {
$table->id();
$table->foreignIdFor(KnowledgeBaseResource::class)
->nullable()
->constrained()
->nullOnDelete();
$table->timestamps();
});
}
}
When I do run php artisan migrate
, I get the following:
SQLSTATE[42000]: Syntax error or access violation: 1059 Identifier name 'company_knowledge_base_resource_matches_knowledge_resource_id_foreign' is too long
(Connection: mysql, SQL: alter table `company_knowledge_base_resource_matches` add constraint `company_knowledge_base_resource_matches_knowledge_resource_id_foreign` foreign key (`knowledge_base_resource_id`) references `knowledge_base_resources` (`id`) on delete set null)
Extra frustrating because the table was created successfully, but it’s just adding the foreign key constraint that fails.
In the past, the workaround was to have to write the foreign key relationship manually
Schema::create('company_knowledge_base_resource_matches', function (Blueprint $table) {
$table->id();
$table->foreignIdFor(KnowledgeBaseResource::class)->nullable();
$table->timestamps();
$table->foreign('knowledge_base_resource_id', 'my_foreign_index')
->references('id')
->on('knowledge_base_resources')
->constrained()
->nullOnDelete();
});
This leaves more room for error and is just a little bit ugly.
With Laravel 10.8.0 you can now specify the index name when calling constrained()
Schema::create('company_knowledge_base_resource_matches', function (Blueprint $table) {
$table->id();
$table->foreignIdFor(KnowledgeBaseResource::class)
->nullable()
->constrained(indexName: 'my_foreign_index')
->nullOnDelete();
$table->timestamps();
});
Voila! Now your index name will be my_foreign_index
and the migration runs without exception. Of course, if you love verbosity and precision like I do, you’ll probably choose a better index name than that