Weave 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

Factory Laravel Package

analogue/factory

A lightweight model factory for Laravel that generates fake Eloquent model instances for testing and seeding, with a fluent API for defining attribute blueprints, sequences, and relationships so you can quickly build realistic test data.

View on GitHub
Deep Wiki
Context7

Getting Started

analogue/factory is glue, not a framework: it lets you keep writing Laravel-style model factories (factory(Entity::class)->create()) while the persistence actually goes through Analogue's data mapper instead of Eloquent. That matters because Analogue entities are plain PHP objects — they have no save(), no newQuery(), and no Eloquent relationship proxies — so Laravel's stock factory builder would choke on them.

Minimal setup:

  1. composer require --dev analogue/factory alongside analogue/orm and a matching illuminate/* version.
  2. Register the package's service provider. On Laravel ≤5.4 that means appending it to providers in config/app.php; on 5.5+ it may auto-discover — check composer.json for extra.laravel.providers before adding it manually.
  3. Confirm which Laravel generation the pin targets. The 2018-02 release predates Laravel 8's class-based factories, so you are working in the $factory->define() / database/factories/*.php world.

Where to look first: the package is small enough to read end-to-end in one sitting. Start with the service provider (that's where the factory builder gets swapped in), then the factory class itself — that is the only place the Analogue-specific persistence logic lives. The composer.json require block is your compatibility contract; read it before anything else.

First use case: seeding a dev/test database for an Analogue-backed app. Define a factory keyed by your entity class, call factory(MyEntity::class)->create(), and assert you get back a hydrated, persisted entity from the mapper.

Implementation Patterns

Define factories against entity class names, not mapper names. The key in $factory->define(...) must be the class the mapper resolves, since that's what factory() is called with later.

Treat create() vs make() as a real fork. make() should hand you an unpersisted object — cheap and useful for unit tests. create() implies the mapper's store() ran. Verify this in the source; it's the single behavior most likely to differ from what you expect coming from Eloquent.

Wire relationships explicitly. This is the biggest departure from Eloquent. Eloquent factories populate belongsTo/hasMany through model APIs and lazy relationship objects. Analogue entities just hold properties, so the idiomatic pattern is:

  • Build the parent entity, store it via $manager->mapper(Parent::class)->store($parent).
  • Build the child, assign $child->parent = $parent, store the child.
  • Do the orchestration in a helper or in the factory closure's tail rather than relying on magic, because there is no ->associate() equivalent.

Use factories in test setup, not in production seeders only. Given how thin the package is, its value is mostly in setUp()/seed fixtures where you want to spin up a graph of entities quickly. A pattern that ages well:

protected function setUp(): void
{
    parent::setUp();
    $this->manager = app(\Analogue\ORM\System\Manager::class);
    factory(Order::class)->create(['status' => 'paid']);
}

Wrap it if you need more. Because the abstraction is shallow, a three-line local helper (function make(string $entity, array $attrs = [])) that calls the factory and then re-stores through the mapper gives you an escape hatch on the day the package can't do what you need. Don't be precious about layering on top.

Integration tip — keep factory definitions in one loaded file. The package presumably expects the legacy database/factories/ autoload path. If auto-discovery isn't working, load the file manually from a service provider's boot().

Gotchas and Tips

  • This is legacy software. Last release February 2018, one star, zero dependents. There is effectively no maintenance, no issue triage, and no upgrade path. Do not make it load-bearing in a long-lived codebase without vendoring or forking it into app/ or a local path repository.
  • Laravel 8+ factory classes will not work. The modern class UserFactory extends Factory style with definition() methods postdates this package. If you're on a recent Laravel, this package is a dead end unless you fork it.
  • Eloquent assumptions leak. The stock factory builder's callbacks (afterMaking, afterCreating) were written for models with save(). Test each callback you use; some will silently no-op or throw when handed a plain entity.
  • Identity map / unit-of-work state leaks across tests. Analogue caches entities in the manager's identity map and queues writes in a unit of work. Between tests, flush or clear the manager (check the method name in analogue/orm — it's flush() / clear() territory) or you'll get bizarre "entity already exists" or stale-attribute failures that look like factory bugs.
  • RefreshDatabase may not roll back Analogue writes the way you expect, since it hooks Eloquent/connection-level transactions. Confirm that the mapper uses the same connection instance, and prefer explicit truncation or a transaction wrapper you control.
  • Composer pin mismatches fail late. A wrong illuminate/support constraint can install cleanly and then explode at container-resolution time. Check the installed version against the package's require block before debugging anything else.
  • create() returning a different object than you built is a real possibility with a data mapper. Compare identity if you're asserting on the returned instance.
  • Debugging recipe: dump the entity immediately before store() and after re-fetching by ID. That single diff tells you whether the problem is factory hydration, mapper mapping, or unit-of-work flushing — the three failure domains of this stack.
  • Extension point: the factory class and service provider are the only seams. If you need custom Faker behavior or a different persistence path, subclass the factory there rather than patching inside vendor.
  • Config quirks: there is no config file to speak of, so behavior is entirely determined by what's in src/. Treat the source as the documentation — it's short enough that this is genuinely the fastest route.
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.
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core