skip to Main Content

I’m trying to seed random belongsTo relationships for a Post, but they are all just being created with the same User and Community.

Code:

        $users = AppModelsUser::factory(100)
            ->create();

        $communities = AppModelsCommunity::factory(10)
            ->create();

        AppModelsPost::factory()
            ->for($users->random()->first())
            ->for($communities->random()->first())
            ->create();

After seeding, when I look at the database, the user_id and community_id is 1 for all of the posts.

How do I make it random for each seeded post based on the users and communities created beforehand?

Tried using random() but does not seem to take effect.

3

Answers


  1. Chosen as BEST ANSWER

    I figured it out by using recycle method in the seeder and specifying a an id for each relationship in the factory.

    PostFactory:

        public function definition(): array
        {
            return [
                'user_id' => User::factory(),
                'community_id' => Community::factory(),
                'title' => fake()->sentence(),
                'created_at' => fake()->dateTimeThisMonth(),
            ];
        }
    

    New seeder code:

            $users = AppModelsUser::factory(100)
                ->create();
    
            $communities = AppModelsCommunity::factory(10)
                ->create();
    
            $posts = AppModelsPost::factory(100)
                ->recycle([$users, $communities])
                ->create();
    

    Works great now :D


  2. You can use a closure within a Sequence to generate random user_id and community_id for each post. For example:

    use IlluminateDatabaseEloquentFactoriesSequence;
    
    $users = AppModelsUser::factory(100)->create();
    $communities = AppModelsCommunity::factory(10)->create();
    
    AppModelsPost::factory()
        ->count(50)
        ->state(new Sequence(
            fn (Sequence $sequence) => [
                'user_id' => $users->random()->id,
                'community_id' => $communities->random()->id,
            ]
        ))
        ->create();
    

    In case your code is exactly the same as the one you have provided, it is better to place the User and Community creation directly in the post factory.

    namespace DatabaseFactories;
    
    use AppModelsUser;
    use AppModelsCommunity;
    use IlluminateDatabaseEloquentFactoriesFactory;
    
    class PostFactory extends Factory
    {
        /**
         * Define the model's default state.
         *
         * @return array<string, mixed>
         */
        public function definition(): array
        {
            return [
                'user_id' => User::factory(),
                'community_id' => Community::factory(),
                'title' => fake()->sentence(),
                'created_at' => fake()->dateTimeThisMonth(),
            ];
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search