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

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

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

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

Q&A

解決済

1回答

794閲覧

Laravel5.5 Factory リレーション

rapsody

総合スコア7

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

0グッド

0クリップ

投稿2021/06/09 22:58

編集2021/06/09 23:12

疑問

User、Post、Commentのリレーションがあるテーブルのダミーデータを作成しようとしているのですが、以下のような記述の時、php artisan migrate:refresh --seed
を実行すると、何故Usersテーブルに6つのレコードが作成されるます。
これは、CommentFactoryの中で、PostFactoryが呼ばれてまずそこでuserレコードが3つ作成、その後UserFactoryが呼ばれて3つレコードが作成されているからだと思います。

その時に、無駄なデータ(userレコードの中で使われていないレコード)がと3つあると思うのですが、それが作成されずに、userレコードを3つしか作成されないようにするには、どうすれば良いのでしょうか?

つまり、
users テーブル

idfugahoge
1fugafugahogehoge
2fugafugahogehoge
3fugafugahogehoge

posts テーブル

iduser_idhoge
11hogehoge
22hogehoge
33hogehoge

comments テーブル

idpost_iduser_id
112
223
331

のようなテストデータ作成はどうすれば良いのでしょうか?

DatabaseSeeder.php↓

php

1<?php 2 3use Illuminate\Database\Seeder; 4 5class DatabaseSeeder extends Seeder 6{ 7 /** 8 * Run the database seeds. 9 * 10 * @return void 11 */ 12 public function run() 13 { 14 factory(App\Models\Comment::class, 3)->create(); 15 } 16} 17

CommentFactory.php↓

php

1<?php 2 3use Faker\Generator as Faker; 4 5/* 6|-------------------------------------------------------------------------- 7| Model Factories 8|-------------------------------------------------------------------------- 9| 10| This directory should contain each of the model factory definitions for 11| your application. Factories provide a convenient way to generate new 12| model instances for testing / seeding your application's database. 13| 14*/ 15 16$factory->define(App\Models\Comment::class, function (Faker $faker) { 17 $date = \Carbon\Carbon::now(); 18 return [ 19 'post_id' => function() { 20 return factory(App\Models\Post::class); 21 }, 22 'user_id' => function () { 23 return factory(App\Models\User::class); 24 }, 25 'comment' => $faker->text, 26 ]; 27}); 28
<?php use Faker\Generator as Faker; $factory->define(App\Models\Post::class, function (Faker $faker) { $date = \Carbon\Carbon::now(); return [ 'title' => $faker->jobTitle, 'user_id' => function () { return factory(App\Models\User::class); } ]; });
<?php use Faker\Generator as Faker; /* |-------------------------------------------------------------------------- | Model Factories |-------------------------------------------------------------------------- | | This directory should contain each of the model factory definitions for | your application. Factories provide a convenient way to generate new | model instances for testing / seeding your application's database. | */ $factory->define(App\Models\User::class, function (Faker $faker) { $age = rand(20, 100); return [ 'name' => $faker->name, 'email' => $faker->unique()->safeEmail, 'password' => '$2y$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm', // secret 'remember_token' => str_random(10), ]; });

リレーション自体はよくある、postsテーブルには$user_idが紐づいていて、comments テーブルには$user_idと$post_idが紐づいています。
一応↓にマイグレーションファイルを載せます。

php

1<?php 2 3use Illuminate\Support\Facades\Schema; 4use Illuminate\Database\Schema\Blueprint; 5use Illuminate\Database\Migrations\Migration; 6 7class CreateUsersTable extends Migration 8{ 9 /** 10 * Run the migrations. 11 * 12 * @return void 13 */ 14 public function up() 15 { 16 Schema::create('users', function (Blueprint $table) { 17 $table->increments('id'); 18 $table->string('name'); 19 $table->string('email', 191)->unique(); 20 $table->string('password'); 21 $table->rememberToken(); 22 $table->timestamps(); 23 }); 24 } 25 26 /** 27 * Reverse the migrations. 28 * 29 * @return void 30 */ 31 public function down() 32 { 33 Schema::dropIfExists('users'); 34 } 35}
<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreatePostsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('posts', function (Blueprint $table) { $table->increments('id'); $table->integer('user_id'); $table->string('title'); $table->string('content'); $table->timestamps(); $table->softDeletes(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('posts'); } }
<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateCommentsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('comments', function (Blueprint $table) { $table->increments('id'); $table->integer('post_id'); $table->integer('user_id'); $table->string('comment'); $table->timestamps(); $table->softDeletes(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('comments'); } }

補足情報(FW/ツールのバージョンなど)

Laravel5.5

追記

正直「userレコードが6つあってそのうち3つは、commentやpostに使われていて、3つは使われていない」
というシチュエーションは全然良い(可能性はあると思うので)のですが
何となく気になって抜け出せなくなったので、ご教示いただきたいです。

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2021/06/10 01:17

思います、じゃなく、事実として観測してからでも良いのではないかと。Log::debug()を各所に仕込んでどういう動きになっているかを見るとか。
rapsody

2021/06/10 13:49

すみません、 Log::debug()を仕込むと、事実であることが確認できました。
guest

回答1

0

自己解決

//postsテーブルとusersテーブルを3件作成する $posts = factory(App\Models\Post::class, 3)->create(); //作成した$postに対してコメントをそれぞれ3件作成する。キーを指定することで属性をオーバーライドできる $posts->each(function($post){ factory(App\Models\Comment::class, 3)->create(['post_id' => $post->id,'user_id' => $post->user_id]); });

↑のように書くことで解決しました。
Log::debug()で$posts中に何が入っているのかを確認すれば、難しい話ではなかったです。

投稿2021/06/15 23:49

rapsody

総合スコア7

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問