SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint - Laravel
Merhabalar bugün sizlere geçenlerde geliştirmeye başladığım twiyollarda sitesinin yorum-yanıt sistemini yaparken karşılaştığım bir sorunu anlatacağım. Soruna geçmeden önce şunlardan bahsedeyim. Siteyi Laravel framework'ünü ve onun popüler open source admin paneli olan Voyager ile geliştirdim. Bu sorunla karşılaşmak için Voyager kullanmanız yeterli aslında buna sorun demekte çok mantıklı gelmiyor bana sadece biraz dikkat etmemiz gereken bir ayrıntı var.
Problem
Hemen olayı size simule edeyim. Laravel kullanarak bir blog sitesi geliştirdiğimizi düşünelim. Anasayfa, tüm blogların sergileneceği blog sayfası vs geliştirdik. Artık bloglarımıza insanların yorum yazabilmelerini istiyoruz ve kolları sıvadık. Modelimizi, migration ve controller'ımızı oluşturduk. Her şey tamam taki php artisan migrate
komutunu çalıştırana kadar :)
Böyle bir sonuçla karşınıza geldi. Biraz kurcalama ve araştırmam sonucunda User
migration dosyasındaki bir durumdan dolayı olduğunu gördüm. Peki ne bu?
Yukarıdaki bu ekran resminde şu satıra dikkat etmenizi istiyorum.
$table->bigIncrements('id');
Bu bigIncrements('id')
otomatik arttırımlı imzalanmamış büyük (UNSIGNED BIGINT) bir id
birincil anahtar kolonu oluşturuyor. Başka bir biçimde de bunu yapmamızı sağlayan bir alias'da bulunmakta oda bu: $table->id();
.
Benim yorum tablomun migration kodları şu şekildi:
Schema::create('comments', function (Blueprint $table) {
$table->id();
$table->integer('post_id')->unsigned();
$table->integer('user_id')->unsigned();
$table->text('comment');
$table->foreign('post_id')
->references('id')->on('posts')
->onDelete('cascade');
$table->foreign('user_id')
->references('id')->on('users')
->onDelete('cascade');
$table->timestamps();
});
Tabi burdaki mantık hatasını ilk başta görmemiştim her şey benim için o zaman çok normaldi. Burdaki hata çok basit bir şekilde foreign key eklerken integer olan bir kolona referans olarak bir başka tablodaki bigint bir kolon göstermek çokta mantıklı bir hareket değil. Çünkü referans olarak gösterdiğimiz id
kolonu bizim comment
tablomuzdaki user_id
alanınından taşabilir. Bu yüzden php artisan migrate
komutumuz bize bir hata ile döndü.
Çözüm
Evet çözüme gelecek olursak iki seçenek var.
- Hali hazırda oluşmuş olan
user
tablomuzu güncelleyipid
kolonunuinteger
yapmak. - Yeni oluşturmaya çalıştığımız
comment
tablomuzunuser_id
kolonunubigint
yapmak.
Ben ilk başta internette araştırdığımda gözüme çalınan bu bigint
kolonu int
kolonuna çevirmeyi denedim. Burda başka bir sorunla karşılaştım tabikide. Voyager admin paneli'ni kullandığım için ben Laravel'in user
tablosuna foreign key eklemiş ve roles
tablosu ile ilişkilendirmiştim. Bu sebepten dolayı ilk çözüm denemem başarısızlıkla sonuçlanmıştı.
Bir duruma çok odaklandığınızda gözünüzün önündeki en basit çözüm bile gözünüze gözükmeyebiliyor.
Tam bu sırada çaresizlik ve güçsüzlük hissi içinde hissederken kendimi o basit çözüm gözüme çalındı :). Gözüme çalınan bu çözüm ikinci seçenek olan comment
tablomuzun user_id
kolonunu bigint
yapmak idi.
comment
tablomun migration dosyası son olarak bu şekli almış oldu:
Schema::create('comments', function (Blueprint $table) {
$table->id();
$table->integer('post_id')->unsigned();
$table->bigInteger('user_id')->unsigned();
$table->text('comment');
$table->foreign('post_id')
->references('id')->on('posts')
->onDelete('cascade');
$table->foreign('user_id')
->references('id')->on('users')
->onDelete('cascade');
$table->timestamps();
});
Migration dosyamı bu şekilde düzenleyip php artisan migrate
komutumu çalıştırdıktan sonra başarılı bir şekilde comment
tablomu oluşturmuş oldum :).
Peki aynı sorunu ben neden post_id
kolonunda da yaşamadım?
Voyager post
tablosunun migration dosyasında id
kolonunu oluştururken bigIncrements('id')
değil increments('id')
kullanmış olması.
Voyager Post Tablosu Migration Dosyası
// Create table for storing roles
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->integer('author_id');
$table->integer('category_id')->nullable();
$table->string('title');
$table->string('seo_title')->nullable();
$table->text('excerpt');
$table->text('body');
$table->string('image')->nullable();
$table->string('slug')->unique();
$table->text('meta_description');
$table->text('meta_keywords');
$table->enum('status', ['PUBLISHED', 'DRAFT', 'PENDING'])->default('DRAFT');
$table->boolean('featured')->default(0);
$table->timestamps();
//$table->foreign('author_id')->references('id')->on('users');
});
Evet arkadaşlar bir blog yazımın daha sonuna geldim sürç-i lisan etti isem affola. Lütfen görüşlerinizi yorumda belirtin. Sağlıklı kalın.
Yorumlar
-
gghfhfghghfhgf - 3 yıl önce
fxgxgcghcgcghcghjghj