Extend/override Eloquent create method - Cannot make static method non static
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
# Extend/override Eloquent create method - Why You Get the "Cannot make static method non static" Error
As a senior developer working with Laravel and Eloquent, we often dive into extending core functionality. One common point of confusion arises when attempting to override static methods like `create()` in an Eloquent Model. You might find yourself running into errors like `Cannot make static method Illuminate\Database\Eloquent\Model::create() non static in class MyModel`, even when your intention is simply to add custom logic before saving a record.
This post will dissect why this error occurs and provide the correct, idiomatic ways to implement custom creation logic in your Eloquent models.
## Understanding Static Methods and Overriding in Laravel
To understand the error, we must first grasp how static methods work in PHP and within the Laravel framework. A static method belongs to the class itself, not to any specific instance of that class. When you call a static method (e.g., `MyModel::create($data)`), PHP resolves it directly on the class definition.
When you try to override a static method, you are essentially telling PHP that this method should no longer be purely static, which causes a conflict with how Laravel expects its static methods to behave across the framework. The error message indicates that the system is detecting an attempt to change the fundamental nature of a static method in a way that breaks static method inheritance rules within Eloquent's structure.
Your goalâadding authentication checks before creating a recordâis perfectly valid, but trying to override the static `create()` method directly often leads to this conflict because Eloquent expects its static methods to remain fully static for global access.
## Why Your Current Approach Fails
Let's look at the typical scenario:
```php
// In MyModel.php
public function create($data) {
if (!Namespace\Auth::isAuthed())
throw new Exception("You can not create a post as a guest.");
parent::create($data); // This calls the parent static method
}
```
When you attempt to call this via `$model->create(...)` or `MyModel::create(...)`, the framework expects the base functionality to remain accessible statically. By modifying the static signature, you create an inconsistency that Laravel's internal machinery flags as illegal when attempting standard static calls.
## The Correct Solutions: Instance vs. Static Logic
Instead of trying to override the core static `create()` method, the best practice in modern Laravel development is to separate concerns: use static methods for global operations and instance methods for object-specific logic.
### Solution 1: Use a Custom Instance Method (Recommended)
For actions that depend on the state or context of a specific model instance (like authentication checks), you should implement the logic within an instance method. This ensures that the creation process is tied to a specific model, not a global static call.
Instead of relying on `$model->create()`, you interact with the model's methods directly:
```php
// In MyModel.php
// Keep the standard static create for framework compatibility (or remove it if not needed)
public static function create(array $data)
{
return parent::create($data); // Let the base Eloquent handle the DB save
}
// Add an instance method for custom, context-aware creation logic
public function createCustom(array $data)
{
if (!Namespace\Auth::isAuthed()) {
throw new Exception("You can not create a post as a guest.");
}
// Now use the parent's static method to perform the actual save
return parent::create($data);
}
```
**How to call it:** You must now instantiate the model first:
```php
$f = new MyModel();
$post = $f->createCustom([
'post_type_id' => 1,
'to_user_id' => Input::get('toUser'),
'from_user_id' => 10,
'message' => Input::get('message')
]);
```
### Solution 2: Using Model Observers or Mutators (For Data Manipulation)
If your goal is purely to manipulate data *before* it hits the database (e.g., adding timestamps or sanitizing fields), consider using Model Observers or Mutators instead of overriding core static methods. This keeps the model focused on its data structure, adhering to the principles outlined by the Laravel team at [laravelcompany.com](https://laravelcompany.com).
## Conclusion
The error you encountered is a strong indicator that you are attempting to override a method designed for static, global access in an instance-based context. As developers, we must respect the framework's design patterns. For conditional logic like authentication checks, implementing custom methods on the model **instance** (Solution 1) provides cleaner separation of concerns and avoids breaking the static contract of Eloquent. By shifting your custom logic to instance methods, you maintain compatibility while achieving your desired business rule enforcement.