On a recent code review, I was asked why some lines in a seeder used for($model)
with a factory, and others used recycle($model)
?
I liked the question, since it showed me the code reviewer was paying attention, which I always appreciate.
After typing up the answer inside the pull request, I thought it might be helpful to share the answer here as well.
My default is to use for()
when I want to specify a related model for the factory to use.
But in some cases, where you have more complex chains of factories, recycle()
can produce more readable code.
I'll simplify the example from the real code base, but I think a concrete example would be helpful:
- The
Survey
model belongs to aUser
model and to aClient
model. - The
Client
model also belongs to aUser
model.
In a case like this, if I only use for($user)
then the survey will be related to my user, but the generated client would have a different user related to it.
Maybe in some cases, that doesn't matter, but in this case it did.
So by specifying recycle($user)
then both the survey and the client will have the same user.
If I wanted to set this up only using for
, it would take extra code:
// longer example using only `for()`
$user = User::factory()->create();
$client = Client::factory()->for($user)->create();
$survey = Survey::factory()->for($user)->for($client)->create();
// shorter example using `recycle()`
$user = User::factory()->create();
$survey = Survey::factory()->recycle($user)->create();
Notice how in the second, shorter example, I don't have to mention the client at all.
The recycle
method will pass my $user
into any subsequent factories that need a user.
So when SurveyFactory
calls ClientFactory
, that $user
will automatically be used.
This is a very simple example, only saving one line of code. But imagine the user and client required a lot more data to set up, or you had a chain of more than 2 factories to coordinate.
You can quickly see where recycle
is a superior approach when needed.
Here to help,
Joel
P.S. I love figuring tricky things out. Are you stuck on something?