简体   繁体   中英

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();
});

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();
});

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');
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM