質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Laravel 5

Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

Q&A

解決済

2回答

6901閲覧

Laravelで外部キー制約付きのテーブルにシーディングしたいのですがどうしてもうまく行きません><

YorihiroKatsuki

総合スコア70

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Laravel 5

Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

0グッド

0クリップ

投稿2017/05/16 03:25

編集2017/05/16 03:26

###前提・実現したいこと
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

何卒宜しくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

usersテーブルのidカラムは連番の自動付与では無いようなので、
Userモデルの定義に以下を加えてから、やってみてください。

PHP

1 2class User extends Authenticatable 3{ 4 // 前後省略 5 6 // 追加 7 public $incrementing = false; 8 9 // 前後省略 10}

投稿2017/05/16 10:25

Archsted

総合スコア452

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YorihiroKatsuki

2017/07/12 09:07

ご返信遅くなり申し訳ございません>< ご提示頂いた方法で解決出来ました! ありがとうございました!
guest

0

携帯からなので簡潔にですが、レコード追加時にattachメソッドで関連付けが必要だと思います。

訂正

associateメソッドだったと思います!

attachはmany vs manyの時ですね。

投稿2017/05/16 03:39

編集2017/05/16 03:41
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YorihiroKatsuki

2017/05/16 06:31

外出中にご回答ありがとうございます>< associateメソッドを使って以下のようにUserTableSeederクラスのrun()メソッドを変更して見たのですが、全く同じエラーが発生してしまいました。。 (user_idカラムが0になってしまいます) ```PHP public function run() { factory(App\User::class,10)->create()->each(function($u){ $purpose = new App\Purpose(); $purpose->purpose = '目的'; $purpose->user()->associate($u); $purpose->save(); }); } ``` こちらassociate()メソッドの使い方が間違っている、もしくは他に考えられる原因がございましたらご教示頂けませんでしょうか。 お手数おかけして申し訳ございません。 どうぞ宜しくお願い致します。
退会済みユーザー

退会済みユーザー

2017/05/16 07:16

$user->purposes()->save($purpose); じゃないですか? ユーザーインスタンスのpurposesプロパティにpurposeインスタンスを保存という感じで。 後、associateはupdate時に使うものらしいので不要っぽいです。すみません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問