En los tests y en el seeding de la base de datos necesitas insertar registros.
En lugar de indicar manualmente los valores de cada columna, con las factorías de modelos de Laravel puedes definir un conjunto de atributos por defecto para cada modelo Eloquent.Todas las nuevas aplicaciones Laravel incluyen database/factories/UserFactory.php.
namespace Database\Factories;use Illuminate\Database\Eloquent\Factories\Factory;use Illuminate\Support\Facades\Hash;use Illuminate\Support\Str;class UserFactory extends Factory{ // Cachea la misma contraseña para no rehash cada vez protected static ?string $password; public function definition(): array { return [ 'name' => fake()->name(), 'email' => fake()->unique()->safeEmail(), 'email_verified_at' => now(), 'password' => static::$password ??= Hash::make('password'), 'remember_token' => Str::random(10), ]; }}
Con el helper fake() tienes acceso a la librería Faker, que genera todo tipo de datos aleatorios.
Puedes cambiar la localización de Faker con la opción faker_locale de config/app.php.
Si el modelo usa el trait HasFactory, Laravel localiza automáticamente su factoría.
Busca dentro del namespace Database\Factories una clase cuyo nombre sea el del modelo con el sufijo Factory.Si la convención no coincide, indícalo explícitamente con el atributo UseFactory.
use Illuminate\Database\Eloquent\Attributes\UseFactory;use Database\Factories\Administration\FlightFactory;#[UseFactory(FlightFactory::class)]class Flight extends Model{ // ...}
Los métodos afterMaking y afterCreating te permiten ejecutar lógica adicional tras generar el modelo.
namespace Database\Factories;use App\Models\User;use Illuminate\Database\Eloquent\Factories\Factory;class UserFactory extends Factory{ public function configure(): static { return $this->afterMaking(function (User $user) { // Se ejecuta tras make() (aún no guardado en BD) })->afterCreating(function (User $user) { // Se ejecuta tras create() (guardado en BD) }); } // ...}
También puedes registrar callbacks dentro de un método de estado.
public function withProfile(): static{ return $this->state(fn (array $attributes) => []) ->afterCreating(function (User $user) { $user->profile()->create([ 'bio' => fake()->paragraph(), ]); });}
use App\Models\User;// Genera 1 elemento$user = User::factory()->make();// Genera 3 (devuelve una colección)$users = User::factory()->count(3)->make();
Cuando generas varios modelos y quieres alternar los valores, utiliza Sequence.
use App\Models\User;use Illuminate\Database\Eloquent\Factories\Sequence;$users = User::factory() ->count(10) ->state(new Sequence( ['admin' => 'Y'], ['admin' => 'N'], )) ->create();// Se generarán 5 con admin='Y' y 5 con admin='N'
Con hasAttached() gestionas las relaciones muchos a muchos. También puedes indicar atributos para la tabla pivote.
use App\Models\Role;use App\Models\User;$user = User::factory() ->hasAttached( Role::factory()->count(3), ['active' => true] // Atributos de la tabla pivote ) ->create();
Cuando quieras usar la misma instancia de un modelo en varias relaciones, utiliza recycle().
// Reutilizar el mismo Airline para Ticket y FlightTicket::factory() ->recycle(Airline::factory()->create()) ->create();// Elegir aleatoriamente de una colección$airlines = Airline::factory()->count(3)->create();Ticket::factory()->count(10)->recycle($airlines)->create();