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

vincent15000's avatar

How to avoid duplicate entries with recycle() in a factory / seeder ?

Hello,

I have this code.

// Factory

public function definition(): array
{
    return [
        'branch_id' => Branch::factory(),
        'user_id' => User::factory(),
        'role_id' => Role::factory(),
    ];
}

// Seeder

public function run(): void
{
    $branches = Branch::all();
    $users = User::all();
    $roles = Role::all();

    Right::factory()->recycle($branches)->recycle($users)->recycle($roles)->count(100)->create();
}

I get duplicate entries in the rights table (I want only different triplets branch_id, user_id, role_id).

How it is possible to avoid duplicate entries ?

Thanks for your help.

V

0 likes
1 reply
LaryAI's avatar
LaryAI
AI
Best Answer
Level 58

Hello,

To avoid duplicate entries when using a factory seeder in Laravel, you need to ensure that each combination of branch_id, user_id, and role_id is unique. The recycle() method is not designed to handle this scenario, as it will just reuse the models from the collections you pass to it, which can lead to duplicates if not managed correctly.

Instead, you can manually create unique combinations of branch_id, user_id, and role_id by using a nested loop to iterate over each collection and create a Right model for each unique triplet. Here's how you can modify your seeder to achieve this:

// Seeder

public function run(): void
{
    $branches = Branch::all();
    $users = User::all();
    $roles = Role::all();

    foreach ($branches as $branch) {
        foreach ($users as $user) {
            foreach ($roles as $role) {
                Right::factory()->create([
                    'branch_id' => $branch->id,
                    'user_id' => $user->id,
                    'role_id' => $role->id,
                ]);
            }
        }
    }
}

This code will create a Right for every possible combination of branch_id, user_id, and role_id. However, if you have a large number of branches, users, and roles, this could lead to a very high number of Right records. If you only want a subset of all possible combinations, you could add additional logic to randomly select a certain number of combinations to create.

If you want to ensure that the Right table does not already contain a particular combination before creating a new Right, you can add a check like this:

foreach ($branches as $branch) {
    foreach ($users as $user) {
        foreach ($roles as $role) {
            $exists = Right::where('branch_id', $branch->id)
                           ->where('user_id', $user->id)
                           ->where('role_id', $role->id)
                           ->exists();

            if (!$exists) {
                Right::factory()->create([
                    'branch_id' => $branch->id,
                    'user_id' => $user->id,
                    'role_id' => $role->id,
                ]);
            }
        }
    }
}

This will check the database for an existing record with the same branch_id, user_id, and role_id before creating a new Right. This ensures that you only create unique triplets in your rights table.

1 like

Please or to participate in this conversation.