user9139039
user9139039

Reputation:

Laravel database foreign key

I want to users have a rank like user, admin, editor,... But I can't add foreign key to rank column in user table from rank table.

This is the ranks table migration

Schema::create('ranks', function (Blueprint $table) {
  $table->increments('id');
  $table->string('rank', 32)->charset('utf8')->nullable($value = false);
});

And this is the user table migration

Schema::create('users', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name', 64)->charset('utf8')->nullable($value = false);
    $table->string('email', 128)->unique()->charset('utf8')->nullable($value = false);
    $table->string('password', 128)->charset('utf8')->nullable($value = false);
    $table->integer('rank')->unsigned()->default(1);
    $table->foreign('rank')->references('id')->on('ranks')->nullable($value = false);
    $table->rememberToken();
    $table->timestamps();
});

Upvotes: 1

Views: 337

Answers (2)

xyzale
xyzale

Reputation: 795

If your ranks are fixed a better design would be to add an ENUM field to the users table.

$table->enum('rank', [User::LEVEL_ADMIN, User::LEVEL_EDITOR]);

Where the constants are defined in the User class. You can then get rid of the rank table.

--

If you want to keep the ranks in a separated table to let administrators to manage them for example you can keep it but create tables first and add the foreign key later on.

Also, take advantage of Eloquent conventions and call the foreign key rank_id so you'll not need to specify it in the relationship method in the model.

Schema::create('ranks', function (Blueprint $table) {
  $table->increments('id');
  $table->string('rank', 32)->charset('utf8');
});

Schema::create('users', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name', 64)->charset('utf8');
    $table->string('email', 128)->unique()->charset('utf8');
    $table->string('password', 128)->charset('utf8');
    $table->integer('rank_id')->unsigned();
    $table->rememberToken();
    $table->timestamps();
});

Schema::table('users', function (Blueprint $table) {
    $table->foreign('rank_id')->references('id')->on('ranks');
});

Upvotes: 0

Alexey Mezenin
Alexey Mezenin

Reputation: 163768

By default, users table migration has 2014_10_12_000000 timestamp, so it is created before any migration that were created manually. So change the ranks table migration filename timestamp to create the table before the users table. For example:

2013_10_12_000000_create_ranks_table.php
2014_10_12_000000_create_users_table.php

Also, move FK constraint code to a separate closure:

Schema::create('users', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name', 64)->charset('utf8')->nullable($value = false);
    $table->string('email', 128)->unique()->charset('utf8')->nullable($value = false);
    $table->string('password', 128)->charset('utf8')->nullable($value = false);
    $table->integer('rank')->unsigned()->default(1);
    $table->rememberToken();
    $table->timestamps();
});

Schema::table('users', function (Blueprint $table) {
    $table->foreign('rank')->references('id')->on('ranks')->nullable();
});

Upvotes: 2

Related Questions