###前提・実現したいこと
PHPのLaravel5.4を使っています。
マイグレーションで作ったusersテーブルとpurposesテーブルにシーディングでテスト用の値を同時に入れたいと考えており、Laravelのシーディングを使ったのですが、外部キー制約関連の以下のようなエラーが発生します。
usersテーブルが親テーブル、purposesテーブルが子テーブルで、usersテーブルのid
とpurposesテーブルのuser_id
が関連付いており、マイグレーションの際にuser_id
に外部キー制約をつけています。
コマンドライン上で$ php artisan db:seed --class=UserTableSeeder
を打ち込むと、usersテーブルとpurposesテーブルにテスト用の値が挿入され、かつ、usersテーブルのid
の値が、自動的にpurposesテーブルのuser_id
に入るようにしたいです。
もう2日ほどハマっていて色々ググったりしているのですが、解決出来ないため、ご助言頂けますと嬉しいです!
###発生している問題・エラーメッセージ
以下のエラーメッセージが発生しており、外部キー制約の違反があると怒られています。後ろの方をみると、purposesテーブルのuser_idの値が0になっているために発生しているようです。
以下に各ファイルのコードを記載致しますので、ご確認頂き、アドバイス頂けますと幸いです。
[Illuminate\Database\QueryException] SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`homestead`.`purposes`, CONSTRAINT `purposes_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE) (SQL: insert into `purposes` (`user_id`, `purpose`, `updated_at`, `created_at`) values (0, 目的, 2017-05-16 02:40:24, 2017-05-16 02:40:24))
実行コマンドはこちらです。
PHP
1$ php artisan db:seed --class=UserTableSeeder
###結果
結果として、エラーは出ていますが、usersテーブルへの値の挿入は成功しており、idカラムにもちゃんと値が入っていますが、purposesテーブルには値は入っておりません。
###該当のソースコード
関連する以下のファイルのコードを一つずつ記載致します。
①Eloquentモデルクラス
・User.php
・Purpose.php
②マイグレーションファイル
・usersテーブルのマイグレーションファイル
・purposesテーブルのマイグレーションファイル
③シーディングのためのクラス
・UserTableSeeder.php
④モデルファクトリ
・UserFactory.php
①Eloquentモデルクラス
・User.php
PHP
1namespace App; 2 3use Illuminate\Notifications\Notifiable; 4use Illuminate\Foundation\Auth\User as Authenticatable; 5 6class User extends Authenticatable 7{ 8 use Notifiable; 9 10 protected $fillable = [ 11 'id','name','email','password', 12 ]; 13 protected $hidden = [ 14 'password', 'remember_token', 15 ]; 16 17 //Relation 18 public function purposes() 19 { 20 return $this->hasMany(Purpose::class); 21 } 22}
・Purpose.php
PHP
1namespace App; 2 3use Illuminate\Database\Eloquent\Model; 4 5class Purpose extends Model 6{ 7 //Relation 8 public function user() 9 { 10 return $this->belongsTo(User::class); 11 } 12}
②マイグレーションファイル
・usersテーブルのマイグレーションファイル
PHP
1 public function up() 2 { 3 Schema::enableForeignKeyConstraints(); 4 Schema::create('users', function (Blueprint $table) { 5 $table->engine = 'InnoDB'; 6 $table->string('id')->unique(); 7 $table->string('name'); 8 $table->string('email')->unique(); 9 $table->string('password'); 10 $table->rememberToken();//remember_token追加 11 $table->timestamps();//created_atとupdated_atのカラム追加 12 }); 13 }
・purposesテーブルのマイグレーションファイル
PHP
1 public function up() 2 { 3 Schema::enableForeignKeyConstraints(); 4 Schema::create('purposes', function (Blueprint $table) { 5 $table->engine = 'InnoDB'; 6 $table->increments('id'); 7 $table->string('user_id'); 8 $table->string('purpose'); 9 $table->timestamps();//created_at,updated_at 10 11 $table->index('user_id'); 12 $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); 13 }); 14 }
③シーディングのためのクラス
・UserTableSeeder.php
PHP
1 public function run() 2 { 3 factory(App\User::class,10)->create()->each(function($u){ 4 $purpose = new App\Purpose(); 5 $purpose->user_id = $u->id; 6 $purpose->purpose = '目的'; 7 $purpose->save(); 8 }); 9 }
④モデルファクトリ
・UserFactory.php
PHP
1$factory->define(App\User::class, function (Faker\Generator $faker) { 2 3 static $password; 4 5 return [ 6 'id' => $faker->unique()->sha1, 7 'name' => $faker->name, 8 'email' => $faker->unique()->safeEmail, 9 'password' => $password ?: $password = bcrypt('secret'), 10 'remember_token' => str_random(10), 11 ]; 12});
###試したこと
①UserTableSeeder.phpで試しに$u->id
を$u->name
に変えてみました
同じくエラーは出ましたが、$u->name
の中身はちゃんとusersテーブルに挿入されていたnameカラムの値が入っていました。
このことから、$u->id
として、usersテーブルのidカラムの値を取得しようとすると値が0になってしまい、他の$u->name
などの場合はちゃんと値が取得出来ていることがわかります。
②UserTableSeeder.phpで以下のように記述してみました
Userクラスのpurposes()
メソッドを使うと、外部キーが自動で反映されるのではないかと思い以下のコードのように記述して見ましたが、結果同様のエラーが発生しました。この場合もuser_id
の中身は0
になっていました。
・UserTableSeeder.php
PHP
1 public function run() 2 { 3 factory(App\User::class,10)->create()->each(function($u){ 4 $purpose = new App\Purpose(['purpose'=>'目的']); 5 $u->purposes()->save($purpose); 6 }); 7 }
###補足情報(言語/FW/ツール等のバージョンなど)
より詳細な情報
・PHP
・Laravel5.4
・Homestead/MySQL
何卒宜しくお願い致します。

回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/07/12 09:07