Created
July 25, 2024 13:34
-
-
Save leroy/96f25b1cca5d7b501b4c13875931269f to your computer and use it in GitHub Desktop.
Make Laravel's eloquent model factories stateful.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Illuminate\Database\Eloquent\Model; | |
use Illuminate\Support\Arr; | |
trait StatefulFactory | |
{ | |
/** | |
* Set factory state, which is not persisted to the database. | |
* | |
* Factory state is wiped using clearFactoryState() method. | |
* | |
* @param array $state | |
* @return $this | |
*/ | |
public function factoryState(array $state): static | |
{ | |
return $this->state(function(array $attributes) use ($state) { | |
$factoryStateKeys = $attributes['factoryState'] ?? []; | |
$factoryStateKeys = array_unique(array_merge($factoryStateKeys, array_keys($state))); | |
return array_merge($attributes, $state, ['factoryState' => $factoryStateKeys]); | |
}); | |
} | |
/** | |
* After creating callback with factory state. | |
* | |
* @param callable $callback | |
* @return $this | |
*/ | |
public function afterCreatingWithFactoryState(callable $callback): static | |
{ | |
$factoryState = null; | |
return $this->afterMaking(function(Model $model) use (&$factoryState) { | |
$factoryState = Arr::only($model->getAttributes(), $model->factoryState ?? []); | |
})->afterCreating(function(Model $model) use (&$factoryState, $callback) { | |
$callback($model, $factoryState); | |
}); | |
} | |
/** | |
* Wipes the factory state before persisting to the database | |
*/ | |
protected function clearFactoryState() | |
{ | |
return $this->afterMaking(function(Model $model) { | |
$factoryStateKeys = $model->factoryState ?? []; | |
foreach ($factoryStateKeys as $key) { | |
unset($model->$key); | |
} | |
unset($model->factoryState); | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment