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.
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:
composer require --dev analogue/factory alongside analogue/orm and a matching illuminate/* version.providers in config/app.php; on 5.5+ it may auto-discover — check composer.json for extra.laravel.providers before adding it manually.$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.
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:
$manager->mapper(Parent::class)->store($parent).$child->parent = $parent, store the child.->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().
app/ or a local path repository.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.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.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.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.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.src/. Treat the source as the documentation — it's short enough that this is genuinely the fastest route.How can I help you explore Laravel packages today?