Factory

A factory in Lightpack is a dedicated class that encapsulates the logic for generating consistent, customizable arrays or model instances—typically for testing, seeding, or rapid prototyping. Factories let you define default data structures, produce batches of fake or default data, and override fields as needed.


Why Use Factories?

Factories are one of the most powerful tools for building reliable, maintainable applications—especially when it comes to testing and prototyping. Here’s why they matter in Lightpack:


Factory Base Class

You define a new factory class by extending Factory and implementing the template() method:

class UserFactory extends Factory
{
    protected function template(): array
    {
        $faker = new Faker();

        return [
            'name' => $faker->name(),
            'email' => $faker->unique()->email(),
            'address' => $faker->address(),
            'created_at' => $faker->date('Y-m-d H:i:s'),
        ];
    }
}

Core Methods

Examples:

// Generate a single user entity (returns array)
$user = (new UserFactory)->make();
// Result: ['name' => 'John Doe', 'email' => 'john@example.com', ...]

// Generate a batch of 3 user entities (returns array of arrays)
$users = (new UserFactory)->times(3)->make();
// Result: [['name' => ...], ['name' => ...], ['name' => ...]]

// Generate a single user entity overriding email
$user = (new UserFactory)->make([
    'email' => 'custom@example.com'
]);
// Result: ['name' => 'John Doe', 'email' => 'custom@example.com', ...]

// Batch with overrides - same override applies to ALL items
$users = (new UserFactory)->times(3)->make(['email' => 'same@example.com']);
// All 3 users will have 'same@example.com' as email

Important: The batch count is automatically reset to null after calling make(), so you can reuse the factory instance.


ModelFactory: For Persisted Models

ModelFactory extends Factory and adds support for creating and saving model instances.

In this example we create a ProductFactory class for Product model.

class ProductFactory extends ModelFactory
{
    protected function template(): array
    {
        return [
            'sku' => 'DUMMY_1000',
            'name' => 'Dummy Product',
        ];
    }

    protected function model(): string
    {
        return Product::class;
    }
}

Usage

// Save a single model (returns Product instance)
$product = (new ProductFactory)->save();
// $product is a Product model instance, already inserted

// Save a batch of models (returns array of Product instances)
$products = (new ProductFactory)->times(2)->save();
// $products is an array of 2 Product model instances

// Save with overrides - same override applies to all in batch
$products = (new ProductFactory)
    ->times(2)
    ->save(['name' => 'Batch Name']);
// Both products will have 'name' => 'Batch Name'

Note: save() returns Model instances, not arrays. Use make() if you only need the data arrays without persisting.