SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint - Laravel

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 migratekomutunu çalıştırana kadar :)

SQLSTATE[HY000]:  General error: 1215 Cannot add foreign key constraint

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?

User Migration File

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 commenttablomuzdaki user_id alanınından taşabilir. Bu yüzden php artisan migratekomutumuz 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üncelleyip id kolonunu integer yapmak.
  • Yeni oluşturmaya çalıştığımız comment tablomuzun user_id kolonunu bigint 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_idkolonunda 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 Avatar
    gghfhfghghfhgf - 3 yıl önce
    fxgxgcghcgcghcghjghj

Mesaj alanı doldurulması zorunludur.
Markdown kopya kağıdı.


Haber bültenime abone olun

Aylık bültenime katılın ve yeni hikayeleri asla kaçırmayın.