###前提
学習目的で Laravel を使ってブログサイトを開発しており、現在は投稿にタグを付けたり、表示する投稿をタグで絞り込んだりする機能を実装しているところで、そのために Post モデルと Tag モデルにリレーションを定義し、それぞれのモデルのテーブルとそれらの中間テーブルを作成しました。
データベース管理にはマイグレーション機能を使用しています。
中間テーブル作成時に外部キー制約を定義していなかったことが原因で、Post または Tag のレコードを削除した時、存在しなくなった post_id や tag_id との接続を保持する**"残すべきではないレコード"が中間テーブルに残ってしまう状態になっているため、中間テーブルに外部キー制約を定義しようとしています。**
現状のマイグレーションファイル:
yyyy_mm_dd_hhmmss_create_posts_table.php
php
1<?php 2 3use Illuminate\Support\Facades\Schema; 4use Illuminate\Database\Schema\Blueprint; 5use Illuminate\Database\Migrations\Migration; 6 7class CreatePostsTable extends Migration 8{ 9 public function up() 10 { 11 Schema::create('posts', function (Blueprint $table) { 12 $table->increments('id'); 13 $table->integer('user_id'); 14 $table->string('title'); 15 $table->text('body'); 16 $table->timestamps(); 17 }); 18 } 19 20 public function down() 21 { 22 Schema::dropIfExists('posts'); 23 } 24} 25
Q1. 下記ファイル内で tags テーブルと 中間テーブルの post_tag テーブルをまとめて定義しました。
このような場合、マイグレーションファイルの内容をファイル名から判断しやすくするため?に、別々のファイルに分けるべきなのでしょうか。
yyyy_mm_dd_hhmmss_create_tags_table.php
php
1<?php 2 3use Illuminate\Support\Facades\Schema; 4use Illuminate\Database\Schema\Blueprint; 5use Illuminate\Database\Migrations\Migration; 6 7class CreateTagsTable extends Migration 8{ 9 public function up() 10 { 11 Schema::create('tags', function (Blueprint $table) { 12 $table->increments('id'); 13 $table->string('name')->unique(); 14 $table->timestamps(); 15 }); 16 17 // 中間テーブル 18 Schema::create('post_tag', function (Blueprint $table) { 19 $table->integer('post_id'); 20 $table->integer('tag_id'); 21 $table->primary(['post_id', 'tag_id']); 22 }); 23 } 24 25 public function down() 26 { 27 Schema::dropIfExists('tags'); 28 29 Schema::dropIfExists('post_tag'); 30 } 31} 32
###知りたいこと
Q2. 中間テーブルを(定義)作成後、後から外部キー制約を定義するにはどうすれば良いのでしょうか。
「テーブル定義の変更履歴は残していくべき」ということを学んだことがあるため、マイグレーションをロールバックしてやり直すという方法ではなく、新たなマイグレーションファイルを作成・マイグレートする方法を学びたいと考えています。
ご教授のほどよろしくお願い申し上げます。
###試したこと
doctrine/dbal
を導入後、下記コマンド
php artisan make:migration add_foreign_key_constraints_to_post_tag_table --table=post_tag
で新規マイグレーションファイルを生成し、それを下記のように編集し、
php
1<?php 2 3use Illuminate\Support\Facades\Schema; 4use Illuminate\Database\Schema\Blueprint; 5use Illuminate\Database\Migrations\Migration; 6 7class AddForeignKeyConstraintsToPostTagTable extends Migration 8{ 9 public function up() 10 { 11 Schema::table('post_tag', function (Blueprint $table) { 12 // 外部キー制約 13 $table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade'); 14 $table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade'); 15 }); 16 } 17 18 public function down() 19 { 20 Schema::table('post_tag', function (Blueprint $table) { 21 Schema::dropIfExists('post_tag'); 22 }); 23 } 24} 25
マイグレートした結果、以下のようなエラーが発生しました。
In Connection.php line 647: SQLSTATE[HY000]: General error: 1005 Can't create table 'blog.#sql-c41_b5' (errno: 150) (SQL: alter table `post_tag` add constraint `post_tag_post_id_foreign` foreign key (`post_id`) references `posts ` (`id`) on delete cascade) In PDOStatement.php line 107: SQLSTATE[HY000]: General error: 1005 Can't create table 'blog.#sql-c41_b5' (errno: 150) In PDOStatement.php line 105: SQLSTATE[HY000]: General error: 1005 Can't create table 'blog.#sql-c41_b5' (errno: 150)
###環境
PHP 7.0.30
Laravel 5.4
DB: MySQL
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/07/03 06:04 編集
2018/07/03 06:04
2018/07/03 06:09