LoginSignup
149
129

More than 5 years have passed since last update.

【メモ】【Laravel】外部キー制約付きMigrateがさっぱり動かないときのチェック・ポイント(Mysql)

Last updated at Posted at 2017-11-12

何故人は同じ過ちを繰り返すのか

またもや引っかかったのでいい加減にメモっとく。(数ヶ月ぶり3度目)
Laravelの気遣いに人がついて行けてないパターンの初歩的なアレです。

こんな構成のテーブルを作りたいとするじゃろ

Kobito.rvZZj6.png

とりあえずこう書くじゃろ

1_create_users_table.php
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->increments('id'); //自動採番
            $table->string('name');
        });
    }

2_create_authorities_table.php
    public function up()
    {
        Schema::create('authorities', function (Blueprint $table) {
            $table->increments('id'); //自動採番
            $table->string('name');
        });
    }
3_create_roles_table.php
    public function up()
    {
        Schema::create('roles', function (Blueprint $table) {
            $table->increments('id'); //自動採番
            $table->integer('user_id');
            $table->integer('authority_id');
            $table->foreign('user_id')->references('id')->on('users'); //外部キー参照
            $table->foreign('authority_id')->references('id')->on('authorities'); //外部キー参照
            $table->unique(['user_id', 'authority_id'],'uq_roles'); //Laravelは複合主キーが扱いにくいのでユニークで代用
        });

    }

Migrateするとこうじゃ

$ php artisan migrate
Migration table created successfully.


  [Illuminate\Database\QueryException]                                         
  SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL  
  : alter table `roles` add constraint `roles_user_id_foreign` foreign key (`  
  user_id`) references `users` (`id`))                                         



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

原因

原因は以下の行。

1_create_users_table.php&2_create_authorities_table
            $table->increments('id'); //自動採番
3_create_roles_table.php
            $table->integer('user_id');
            $table->integer('authority_id');

 
increments()で作ったカラムには、実は裏でunsined(符号無し)属性が付与される。要は採番項目なので正の値しか登録できないわけだが、役割テーブル側のuser_idauthority_idには同様の制約を付けていない。

つまり、形式の不一致で落ちているわけですな。

というわけで、以下のように書き換える

Migrationファイル上で符号無し属性を付けるにはunsigned()構文を使えばよい。

役割テーブル作るやつ:3_create_roles_table.php
    public function up()
    {
        Schema::create('roles', function (Blueprint $table) {
            $table->increments('id'); //自動採番
            $table->integer('user_id')->unsigned();
            $table->integer('authority_id')->unsigned();
            $table->foreign('user_id')->references('id')->on('users'); //外部キー参照
            $table->foreign('authority_id')->references('id')->on('authorities'); //外部キー参照
            $table->unique(['user_id', 'authority_id'],'uq_roles'); //Laravelは複合主キーが扱いにくいのでユニークで代用
        });

    }

後はいつもどおりMigrateをかければOK。

補足

当記事は2017/11/11投稿記事の再投稿です。
前記事は内容がアレだったので閲覧数が付く前に削除した次第。正直すまんかった。

149
129
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
149
129