- The Core Idea
- Suggested Directory Structure
- Example: Using Traits in a Model
- Reusability
- Tip
- Conclusion
If you've been working with Laravel—or MVC frameworks in general—for a while, you've likely run into the same issue I have: the Model file becomes huge over time. Just take a look at the illustration below.
From properties like fillable and casts, to scopes, relationships, accessors, mutators, and even custom builders or collections—everything ends up in a single model file. As your project grows, managing such bloated files becomes a pain.
Naturally, we need to split these responsibilities into smaller parts. But how?
This short article suggests a simple strategy: use Traits to organize your model logic more reasonably. (Note: this is not a call to refactor your production code overnight 😃)
The Core Idea
Split common logic into separate Traits and place them under a Concerns folder (a common Laravel convention).
Naming Guidelines:
-
Name your traits based on their function or responsibility.
-
Common trait names include:
HasAttributesHasQueryScopesHasRelations- ...
This allows:
- Code reuse across models
- Easier maintenance
- Better separation of concerns
Suggested Directory Structure
App/
└── Models/
├── User.php
└── Concerns/
├── HasAttributes.php
├── HasQueryScopes.php
└── HasRelations.php
Example: Using Traits in a Model
File: app/Models/Concerns/HasQueryScopes.php
namespace App\Models\Concerns;
trait HasQueryScopes
{
public function scopeActive($query)
{
return $query->where('is_active', true);
}
public function scopeSearch($query, $term)
{
return $query->where('name', 'like', "%{$term}%");
}
}
File: app/Models/User.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use App\Models\Concerns\HasQueryScopes;
use App\Models\Concerns\HasAttributes;
use App\Models\Concerns\HasRelations;
class User extends Model
{
use HasQueryScopes, HasAttributes, HasRelations;
protected $fillable = ['name', 'email', 'password'];
}
Reusability
If multiple models share the same behavior—like query scopes or relationships—you can simply reuse the traits.
class Post extends Model
{
use HasQueryScopes, HasRelations;
}
Tip
From now on, if your model requires a new set of related logic (e.g. audit logs, computed attributes...), just create a new trait inside the Concerns folder and apply it.
Conclusion
Organizing your Laravel models using traits is a lightweight, effective, and scalable way to manage growing codebases. It helps make your models more readable and maintainable—especially on large teams or long-term projects.
Happy coding!