Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

panthro's avatar

Getting a random row in a seed?

In my seed, I want to created 20 rows in my like table...

Like::factory()->count(20)->for(
        Post::inRandomOrder()->first() ?? Post::factory(), 'likeable'
)->create();

In the for I get a random post or if no post is available I create one.

The issue is, all 20 rows created in the like table have the same "random" post id, almost as if the random selector is only running once.

Why is this the case?

0 likes
13 replies
Niush's avatar

Use for each loop. for's argument is only resolved once.

panthro's avatar

@Niush could you show an example how foreach works with factories?

iftekhs's avatar

Try this in your factory file ->

use App\Models\Post; 

$factory->define(App\Like::class, function (Faker\Generator $faker) {
  return [
    'user_id' => Post::all()->random()->id,
    'time' => now();
  ];
});

or Try a for loop ->


for ($x = 0; $x <= 20; $x++) {
  Like::factory()->create([
     'post_id' => Post::all()->random()->id ?? Post::factory(),
]);      
}

1 like
sr57's avatar

@iftekhs

With only one post created, the loop will only create the same post.

You need 2 loops, one 2 create posts and the second to create likes.

Feel free to give this example.

1 like
iftekhs's avatar

@sr57 As @sr57 said check if you have 1 post instead of multiple. if you only have 1 post you can just run a simple post factory to create multiple.

Post::factory(10)->create();

and then try looping for likes and get a random post_id from your POST model.

1 like
panthro's avatar

@iftekhs this does not answer the question, it's about calling the relationship from the seed, not using inline relations on the factory.

iftekhs's avatar

@panthro I don't understand don't you want 20 like table rows with random post_id? or basically the POST related to it?

panthro's avatar

@iftekhs I want to create 20 rows for a polymorphic relation, but a random polymorphic relation. See my original post. It's using the same random row each time.

iftekhs's avatar

Maybe try this ->

$post = Post::inRandomOrder()->first();
if(!$post) {
$post = Post::factory()->create();
}
Like::factory(20)->create([
'post_id' => $post->id,
]);

or for many posts ->

$posts = Post::inRandomOrder()->limit(5)->get();
if(!$posts) {
$posts = Post::factory(5)->create();
}
foreach($posts as $post){
Like::factory(20)->create([
'post_id' => $post->id,
]);
}
Vitalii96's avatar

Try this .

class AuthorSeeder extends Seeder { /** * Run the database seeds. */ public function run(): void { for ($i = 0; $i < 12; $i++) { $this->seed(rand(1,10)); } }

public function seed(int $count)
{
    Author::factory()->has(Post::factory($count))->create();

}

}

Please or to participate in this conversation.