"General error: 1005 Can't create table" Using Laravel Schema Build and Foreign Keys

Viewed 51339

Essentially, I am having the same issue as this guy, minus the table prefix. Because I have no table prefix, his fix does not work. http://forums.laravel.com/viewtopic.php?id=972

I am trying to build a table using Laravel's Schema Builder like this:

Schema::create('lessons', function($table)
{
    $table->increments('id');
    $table->string('title')->nullable();
    $table->string('summary')->nullable();
    $table->timestamps();
});

Schema::create('tutorials', function($table)
{
    $table->increments('id');
    $table->integer('author');
    $table->integer('lesson');
    $table->string('title')->nullable();
    $table->string('summary')->nullable();
    $table->string('tagline')->nullable();
    $table->text('content')->nullable();
    $table->text('attachments')->nullable();
    $table->timestamps();
});

Schema::table('tutorials', function($table)
{
    $table->foreign('author')->references('id')->on('users');
    $table->foreign('lesson')->references('id')->on('lessons');
});

The issue is, when I run this code (in a /setup route), I get the following error:

SQLSTATE[HY000]: General error: 1005 Can't create table 'tutorials.#sql-2cff_da' (errno: 150)

SQL: ALTER TABLE `tutorials` ADD CONSTRAINT tutorials_author_foreign FOREIGN KEY (`author`) REFERENCES `users` (`id`)

Bindings: array (
)

Based on posts around the web and the limited documentation available on how to setup Laravel's Eloquent relationships, I'm not sure what I'm doing wrong...

users already exists and it does have an id field that is auto_increment. I am also setting up my models with the proper relationships (belongs_to and has_many), but as far as I can tell this is not the issue-- it's the database setup. The DB is InnoDB.

What exactly am I doing wrong with the foreign key?

15 Answers

You have to give the integer an unsigned flag in Laravel 5.4, like this:

public function up()
{
    Schema::create('posts', function (Blueprint $table) {
        $table->increments('post_id');
        $table->text('title');
        $table->text('text');
        $table->integer('employee_post_id_number')->unsigned();
        $table->foreign('employee_post_id_number')->references 
        ('employee_id_number')->on('employees');
        $table->timestamps();
    });
}

Basically, you get this error because the migration command creates tables in an order which does not match the FK reference you are providing for tables.

Like if you want to create an FK which should refer to the id in users table then users table must exist.

In your example, the author and lesson tables need to be created first.

So, I solved this by creating the tables (one by one) in such order, where I can successfully refer the FK to an existing table. So that Php Artisan Migration cannot decide the order.

Another solution is, you can simply rename the tables or the timestamps provided by migration command .

By using:

 $table->unsignedInteger('author');

instead of:

 $table->integer('author');

the problem will be solved.

The problem is that integer generates an int(11) variable while you need an int(10) variable. unsignedInteger will make it for you.

One of the reasons for this error can be the time and date creation of the migration files. For example , if we have tasks which belongs to some tasks groups, and there is references like: "create_tasks_table

$table->id();
        $table->string('task_name');
        $table->integer('task_group')->unsigned();
        $table->foreign('task_group')
            ->references('id')->on('tasks_groups')->onDelete('cascade');
        $table->longText('task_desc');...."

it is important to create migration file for tasks_groups first (in the name of file we can see the time and date of creation) and than we should create tasks which belongs to some tasks_groups

also it is better to form the migration files with relations like this:

enter codeOne of the reasons for this error can be the time and date creation of the migration files. For example , if we have tasks which belongs to some tasks groups, and there is references like:

"create_tasks_table

        $table->id();
        $table->string('task_name');
        $table->integer('task_group')->unsigned();
        $table->foreign('task_group')
            ->references('id')->on('tasks_groups')->onDelete('cascade');
        $table->longText('task_desc');...."

it is important to create migration file for tasks_groups first (in the name of file we can see the time and date of creation) and than we should create tasks which belongs to some tasks_groups

also

migration table should look like this

`use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema;

class CreateTasksTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('tasks_groups', function (Blueprint $table) { $table->increments('id'); $table->string('group_name'); $table->string('slug'); $table->timestamps(); });

    Schema::create('tasks', function (Blueprint $table) {
        $table->id();
        $table->string('task_name');
        $table->integer('task_group')->unsigned();
        $table->foreign('task_group')
            ->references('id')->on('tasks_groups')->onDelete('cascade');
        $table->longText('task_desc');
        $table->string('izvrsioc');
        $table->string('ulogovani_rukovodioc');
        $table->date('time_finishingtask');
        $table->string('prioritet_izrade')->default('');
        $table->string('file_1')->nullable();
        $table->string('file_path1')->nullable();
        $table->string('file_2')->nullable();
        $table->string('file_path2')->nullable();
        $table->string('file_3')->nullable();
        $table->string('file_path3')->nullable();
        $table->longText('dodatni_komentar');
        $table->boolean('zavrsen_task')->default(false);
        $table->boolean('otkazan_task')->default(false);
        $table->timestamps();
    });
}

/**
 * Reverse the migrations.
 *
 * @return void
 */
public function down()
{
    Schema::dropIfExists('tasks');
    Schema::dropIfExists('tasks_groups');
}

}`

it is better if there is relation

I was facing this problem, I just solved it this way Add ->unsigned() with any column you add to represent a relationship example: errorr $table->integer('lesson');

right is $table->integer('lesson')->unsigned();

Related