Forget newFactory()
: Use Laravel's UseFactory Attribute Like a Pro
newFactory()
: Use Laravel's UseFactory Attribute Like a ProWith Laravel constantly evolving to make development more expressive and maintainable, one of the latest features introduced in Laravel 10.37+ is the UseFactory
attribute — a modern, PHP 8+ way to explicitly define model-to-factory relationships.
This article dives deep into how UseFactory
simplifies factory usage in Laravel, especially in domain-driven or modular architectures, and how it can streamline your development experience.
🧱 The Problem with Traditional Factory Associations
Traditionally, Laravel relied on a convention-based approach to bind models with their factories. If you created a model named Article
, you had to create a factory named ArticleFactory
and place it in the database/factories
directory. Laravel would then automatically find it using the HasFactory
trait.
But what if your models live in custom namespaces like App\Domains\Content\Models
? What if you follow a more modular or domain-driven design?
In those cases, you were required to manually override the newFactory()
method on each model, like this:
use Database\Factories\ArticleFactory;
class Article extends Model
{
use HasFactory;
protected static function newFactory()
{
return ArticleFactory::new();
}
}
While this approach worked, it added boilerplate code and cluttered your model logic.
✨ Enter UseFactory
: The Declarative Way
Laravel’s UseFactory
attribute provides a cleaner, more elegant way to associate a factory with a model. It uses PHP attributes, introduced in PHP 8, to decorate your model with factory metadata.
✅ Basic Example
use Database\Factories\ArticleFactory;
use Illuminate\Database\Eloquent\Attributes\UseFactory;
#[UseFactory(ArticleFactory::class)]
class Article extends Model
{
use HasFactory;
protected $fillable = ['title', 'body', 'published_at'];
}
That’s it — no need for newFactory()
, no guessing based on naming conventions. Just a clear, explicit declaration.
🧩 Works Seamlessly with Modular and DDD Architectures
If you’re building a Laravel application using Domain-Driven Design (DDD) or module-based architecture, your models might not reside in the default App\Models
namespace. This is where UseFactory
really shines.
Here’s an example from a modular project structure:
namespace App\Domains\Content\Models;
use Database\Factories\ArticleFactory;
use Illuminate\Database\Eloquent\Attributes\UseFactory;
use Illuminate\Database\Eloquent\Model;
#[UseFactory(ArticleFactory::class)]
class Article extends Model
{
use HasFactory;
protected $fillable = ['title', 'body', 'published_at'];
}
And another for a billing module:
namespace App\Domains\Billing\Models;
use Database\Factories\SubscriptionFactory;
use Illuminate\Database\Eloquent\Attributes\UseFactory;
use Illuminate\Database\Eloquent\Model;
#[UseFactory(SubscriptionFactory::class)]
class Subscription extends Model
{
use HasFactory;
}
This approach eliminates the need for repetitive newFactory()
definitions and makes your code cleaner and easier to maintain.
🧠 Laravel’s Factory Resolution Logic
You might wonder: What happens if you define both the $factory
static property and the UseFactory
attribute?
Laravel resolves factories in the following priority:
$factory
static property (legacy style)#[UseFactory]
attribute- Convention-based resolution (e.g.,
ArticleFactory
forArticle
)
This layered fallback ensures that your code won’t break existing factory logic and gives you flexibility to migrate incrementally.
🧑💻 Real-Life Example: Nested Relationships
The UseFactory
attribute isn’t just for models — you can also use it with relationship methods to declare factories for related models.
use Illuminate\Database\Eloquent\Relations\HasMany;
use Database\Factories\CommentFactory;
#[UseFactory(ArticleFactory::class)]
class Article extends Model
{
use HasFactory;
#[UseFactory(CommentFactory::class)]
public function comments(): HasMany
{
return $this->hasMany(Comment::class);
}
}
While the above might not be used commonly, it shows Laravel’s potential direction for more expressive relationship metadata.
👩💻 Benefits of Using UseFactory
Code Clarity
Explicitly linking factories makes your code more self-documenting. When other developers read the model, they immediately know which factory it’s tied to.
✅ Less Boilerplate
No more overriding newFactory()
in every custom-named model.
✅ IDE Support
Modern IDEs like PhpStorm or VS Code can now offer better autocomplete and navigation with attribute metadata.
✅ More Flexibility for Teams
In team environments, clear factory associations reduce confusion and onboarding time.
📸 Image Example
You can visualize a ProductVariant
model in a domain-based folder like this:
namespace App\Modules\Inventory\Models;
use Illuminate\Database\Eloquent\Model;
use Database\Factories\ProductVariantFactory;
use Illuminate\Database\Eloquent\Attributes\UseFactory;
#[UseFactory(ProductVariantFactory::class)]
class ProductVariant extends Model
{
use HasFactory;
protected $fillable = ['sku', 'price', 'stock'];
}
This makes your factory usage consistent and discoverable even across deeply nested domain structures.
🧪 Testing with UseFactory
In your tests, the behavior stays the same:
use App\Domains\Content\Models\Article;
$article = Article::factory()->create();
$this->assertDatabaseHas('articles', [
'id' => $article->id,
]);
Since HasFactory
automatically looks for the UseFactory
attribute, you don’t need to do anything different in your tests.
🧭 Conclusion
The UseFactory
attribute in Laravel is a small but powerful feature that brings modern PHP elegance to a common developer task. Whether you’re building a small app or a large-scale modular system, adopting this attribute can improve code clarity, reduce duplication, and help teams work more effectively.
So next time you’re creating a model in Laravel, try adding #[UseFactory(...)]
instead of writing newFactory()
. Your future self (and teammates) will thank you.