Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Doctrine Factory Laravel Package

stemble/laravel-doctrine-factory

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require stemble/laravel-doctrine-factory
    

    Add the service provider to config/app.php:

    Stemble\DoctrineFactory\DoctrineFactoryServiceProvider::class,
    
  2. Entity Setup: Add the HasFactory trait to your Doctrine entity:

    use Stemble\DoctrineFactory\HasFactory;
    
    #[ORM\Entity]
    class User implements UserInterface
    {
        use HasFactory;
        // ...
    }
    
  3. Create a Factory: Generate a factory using Artisan:

    php artisan make:factory UserFactory --model=App\Entity\User
    

    The factory will be placed in database/factories/UserFactory.php.

  4. Define Factory:

    namespace Database\Factories;
    
    use App\Entity\User;
    use Illuminate\Database\Eloquent\Factories\Factory;
    
    class UserFactory extends Factory
    {
        protected $model = User::class;
    
        public function definition()
        {
            return [
                'name' => $this->faker->name(),
                'email' => $this->faker->unique()->safeEmail(),
                // ...
            ];
        }
    }
    
  5. First Use Case: Create a user in a test:

    use App\Entity\User;
    use Database\Factories\UserFactory;
    
    $user = UserFactory::new()->create();
    

Implementation Patterns

Workflows

  1. Basic Creation:

    // Create a single entity
    $user = UserFactory::new()->create();
    
    // Create multiple entities
    $users = UserFactory::new()->count(5)->create();
    
  2. States: Define reusable states in the factory:

    public function definition()
    {
        return [
            'name' => 'Default User',
        ];
    }
    
    public function admin()
    {
        return $this->state([
            'name' => 'Admin User',
            'role' => 'admin',
        ]);
    }
    

    Usage:

    $admin = UserFactory::new()->admin()->create();
    
  3. Relationships: Use has() and for() for relationships:

    // Create a user with posts
    $user = UserFactory::new()->hasPosts(3)->create();
    
    // Create posts for a user
    $posts = PostFactory::new()->for($user)->create();
    
  4. Sequences: Generate sequential data:

    $users = UserFactory::new()->count(5)->sequence(
        function (Factory $factory) {
            return ['name' => 'User ' . $factory->index + 1];
        }
    )->create();
    
  5. Callbacks: Use afterMaking and afterCreating:

    public function configure()
    {
        return $this->afterCreating(function (User $user) {
            // Post-create logic
        });
    }
    

Integration Tips

  • Testing: Use factories in PHPUnit tests for consistent test data:

    public function test_user_creation()
    {
        $user = UserFactory::new()->create();
        $this->assertDatabaseHas('users', ['email' => $user->email]);
    }
    
  • Seeding: Seed your database with factories in DatabaseSeeder.php:

    public function run()
    {
        User::factory()->count(10)->create();
    }
    
  • Custom Attributes: Override attributes dynamically:

    $user = UserFactory::new()->create([
        'email' => 'custom@example.com',
    ]);
    

Gotchas and Tips

Pitfalls

  1. Entity Manager Awareness: The package uses Doctrine's EntityManager under the hood. Ensure your entity manager is properly configured and injected if you encounter issues with entity persistence.

  2. State Conflicts: States can override each other unexpectedly. Define states carefully and test combinations:

    // Avoid this if 'admin' and 'premium' states both set 'role'
    $user = UserFactory::new()->admin()->premium()->create();
    
  3. Relationship Loading: Relationships (has(), for()) are not loaded by default. Use with() to eager-load:

    $user = UserFactory::new()->hasPosts()->with('posts')->create();
    
  4. Faker Integration: The package relies on Faker for fake data. Ensure Faker is installed (fakerphp/faker) and configured correctly.

  5. Transaction Handling: Factories create entities in a transaction by default. Disable with:

    UserFactory::new()->create(['transaction' => false]);
    

Debugging

  • Factory Not Found: Ensure the factory class name matches the model name (e.g., UserFactory for User model) and is placed in database/factories/.

  • Entity Not Persisting: Check if the EntityManager is properly injected or if the entity has required annotations (e.g., @ORM\Entity).

  • State Not Applying: Verify that states are defined as methods (not properties) and return the correct array structure.

Tips

  1. Reuse Factories: Extend factories for reusable configurations:

    class AdminUserFactory extends UserFactory
    {
        public function definition()
        {
            return parent::definition()->merge([
                'role' => 'admin',
            ]);
        }
    }
    
  2. Customize Faker: Override Faker instances for locale-specific data:

    public function configure()
    {
        return $this->state(new \Faker\Generator());
    }
    
  3. Laravel Mixins: Use Laravel's factory mixins for dynamic attributes:

    User::factory()->state(new class {
        protected $attributes = [];
    
        public function __invoke(Factory $factory)
        {
            return $this->attributes;
        }
    });
    
  4. Performance: For bulk operations, disable callbacks and transactions:

    UserFactory::new()->count(1000)->disableOriginalEvents()->create();
    
  5. Doctrine Events: Listen to Doctrine lifecycle events (e.g., prePersist) alongside factory callbacks for additional control.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui