Skip to content
Advertisement

Laravel/MariaDB: errno 150 “Foreign key constraint is incorrectly formed”

I’m on Laravel 5.4, PHP 5.6, Ubuntu 18.04, MariaDB 10.4.8. When I run php artisan migrate, I get:

In Connection.php line 647:
                                                                                                                     
  SQLSTATE[HY000]: General error: 1005 Can't create table `test-kursach-backend`.`comments` (errno: 150 "Foreign ke  
  y constraint is incorrectly formed") (SQL: alter table `comments` add constraint `comments_post_id_foreign` forei  
  gn key (`post_id`) references `posts` (`id`))                                                                      
                                                                                                                     

In Connection.php line 449:
                                                                                                                     
  SQLSTATE[HY000]: General error: 1005 Can't create table `test-kursach-backend`.`comments` (errno: 150 "Foreign ke  
  y constraint is incorrectly formed")

I’m trying to use https://github.com/klisl/laravel-comments. Before trying to perform a migration with this package I had created DB at phpMyAdmin, had configured .env by adding DB name and stuff, had successfully run php artisan migrate, php artisan make:auth and php artisan make:controller AuthController. Then, after running php artisan vendor:publish --provider="KlislCommentsCommentsServiceProvider" I get 2 new files in migrations folder: date_number_CreateCommentsTable.php and date_number_ChangeCommentsTable.php

Here’s source from these 2 files:

CreateCommentsTable.php:

<?php

use IlluminateSupportFacadesSchema;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateDatabaseMigrationsMigration;

/**
 * Class CreateCommentsTable
 */
class CreateCommentsTable extends Migration
{

    /** @return void */
    public function up()
    {
        Schema::create('comments', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('email');
            $table->text('text');
            $table->integer('parent_id')->nullable(); //разрешаем null; 
            $table->boolean('status')->default(config('comments.show_immediately')); 
            $table->timestamps();
        });
    }

    /** @return void */
    public function down()
    {
        Schema::dropIfExists('comments');
    }

}

ChangeCommentsTable.php:

<?php

use IlluminateSupportFacadesSchema;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateDatabaseMigrationsMigration;

/**
 * Class ChangeCommentsTable
 */
class ChangeCommentsTable extends Migration
{

    /** @return void */
    public function up()
    {
        Schema::table('comments', function (Blueprint $table) { 
            $table->integer(config('comments.key_field'))->unsigned();      
            $table->foreign(config('comments.key_field'))->references('id')->on(config('comments.key_table'));  
            
            if(config('comments.user')){
                $table->integer('user_id')->unsigned()->nullable(); //разрешаем null        
                $table->foreign('user_id')->references('id')->on('users');
            }
        });
    }

    /** @return void */
    public function down()
    {
        Schema::table('comments', function (Blueprint $table) {
            //
        });
    }

}

So then I run php artisan migrate and get the error I’ve written about above.

I’ve already tried adding ->unsigned() at CreateCommentsTable. Also I’ve tried to put the foreign keys out of the function at ChangeCommentsTable like this:

    /** @return void */
    public function up()
    {
        Schema::table('comments', function (Blueprint $table) { 
            $table->integer(config('comments.key_field'))->unsigned();          
            
            if(config('comments.user')){
                $table->integer('user_id')->unsigned()->nullable(); //разрешаем null        
            }
        });

        Schema::table('comments', function ($table){
           $table->foreign(config('comments.key_field'))->references('id')->on(config('comments.key_table'));
        });
        Schema::table('comments', function ($table){
            if(config('comments.user')){
                $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
            }
        });
    }

    /** @return void */
    public function down()
    {
        Schema::dropForeign([config('comments.key_field')]);
        Schema::dropForeign(['user_id']);
        Schema::table('comments', function (Blueprint $table) {
            //
        });
    }

and this:

Schema::table('comments', function ($table){
   $table->foreign(config('comments.key_field'))->references('id')->on(config('comments.key_table'));
    if(config('comments.user')){
        $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
    }
});

As any of didn’t work out, I decided to post the default version of source above. If you help me with this, you really save my day c:

UPD: Here’s source from CommentController.php:

<?php

namespace AppHttpControllers;

use IlluminateHttpRequest;
use Validator;
use Auth;
use AppComment;
use AppPost;


class CommentController extends Controller
{

    /**
     * Processing form - AJAX
     *
     * @param Request $request
     * @return IlluminateHttpJsonResponse
     */
    public function store(Request $request)
    {

        $data = $request->except('_token', 'comment_post_ID', 'comment_parent');
        
        //adding  fields with same names like in table (models)
        $data['post_id'] = $request->input('comment_post_ID');
        $data['parent_id'] = $request->input('comment_parent');
        
        $data['status'] = config('comments.show_immediately');


        $user = Auth::user();

        if($user) {
            $data['user_id'] = $user->id;
            $data['name'] = (!empty($data['name'])) ? $data['name'] : $user->name;
            $data['email'] = (!empty($data['email'])) ? $data['email'] : $user->email;                              
        }

        $validator = Validator::make($data,[
            'post_id' => 'integer|required',
            'text' => 'required',
            'name' => 'required',
            'email' => 'required|email',
        ]);

        $comment = new Comment($data); 


        if ($validator->fails()) {
            return response()->json(['error'=>$validator->errors()->all()]);
        }
        

        $post = Post::find($data['post_id']);

        $post->comments()->save($comment);
        

        $data['id'] = $comment->id;
        $data['hash'] = md5($data['email']);
        $data['status'] = config('comments.show_immediately');
        

        $view_comment = view(env('THEME').'.comments.new_comment')->with('data', $data)->render();

        return response()->json(['success'=>true, 'comment'=>$view_comment, 'data'=>$data]);

    }
}

Advertisement

Answer

I haven’t had posts table so the problem was solved by adding it. I’ll mark this answer as a correct when it’s possible.

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement