1

Consider the below code:

foreach ($departments as $department)
        {
            factory(App\User::class, 100)->create()
            ->each(function ($u) use($department)
            {

                $u->employee()->save(factory(App\Employee::class)->make([
                    'department' => $department,
                    'emp_id' => '',
                ]));

            });

        }

Now for emp_id I want to have incremental value from 1 to 100 for each iteration of the outer foreach loop.

Example:

1st iteration 100 users and 100 employees record should be created with emp_id 1 to 100 with department as 'abc'

2nd iteration again 100 users and 100 employees record should be created with emp_id 1 to 100 with department as 'xyz' and so on.

I tried to declare $i=1 before the factory and then increment $i withing each() but it did not work and gave duplicate key error.

Note that the unique constraint in my table for employee is department-emp_id

Raj
  • 1,928
  • 3
  • 29
  • 53
  • Do you have any (unique) constraints in place on one of these database tables (presumably `employees` table)? – Namoshek Jun 16 '18 at 18:53
  • I have mentioned that already at the end that I have a unique constraint on the combined columns department-emp_id together – Raj Jun 16 '18 at 18:55
  • Sorry, I totally overlooked it due to the color. Is `$department` an integer or a model? – Namoshek Jun 16 '18 at 18:56
  • $department is simply different name for departments like 'abc', 'xyz' and so on – Raj Jun 16 '18 at 18:57
  • I think your solution should work and it must be a minor detail that is causing troubles. Have you added the counting variable to the `use` part of your function within `each()`? Have you tried dumping the content of your counting variable within `each()`? – Namoshek Jun 16 '18 at 19:02
  • Yes I tried it. It always remains 1 which is the starting value and does not increment even if I do $i++ – Raj Jun 16 '18 at 19:05

1 Answers1

1

This is a tricky one. The value of your index variable is not updating because when you pass primitives to a function in the use clause, they are copied. Only objects are passed by reference by default.

To get around this, you need to explicitely pass your index variable as reference by prepending an &:

foreach ($departments as $department)
{
    $i = 1;
    factory(App\User::class, 100)->create()
        ->each(function ($u) use ($department, &$i)
        {
            $u->employee()->save(factory(App\Employee::class)->make([
                'department' => $department,
                'emp_id' => $i++,
            ]));
        });
}

I hacked together a small example to show the difference over at 3v4l.

Namoshek
  • 6,394
  • 2
  • 19
  • 31