Siphon
Siphon

Reputation: 1061

Laravel - Unable to override the create method for a model

When overriding the base Laravel model create method, the application fails. No errors are sent back to the browser, and the server logs are empty. The strange thing, it works just fine without the override. Not sure what I'm doing wrong.

Simplified controller function:

public function save(Request $request, $id = 0) {
    $myModel = MyModel::find($id);
    $data = $request->all();

    if (!$myModel) // Create a new row
    {
        $myModel = MyModel::create($data);
    }

    // ...
}

This works fine until I add this function to the model:

class MyModel extends Model
{
    // ...

    public static function create($attributes = [])
    {
        return parent::create($attributes);
    }

    // ...
}

Just to clarify, I'm not looking for a different way to implement this. I just need to know why the parent call is failing for me.

Here's some server info...

Upvotes: 5

Views: 4645

Answers (4)

Alex
Alex

Reputation: 34998

Based on PiTheNumber's answer and miken32's comment as well as https://stackoverflow.com/a/64935310/288568 the best way seems to be to use the creating event and return false,

protected static function booted(): void
{
    static::creating(function (MyModel $myModel) {
        if($dontWantToCreateIt) {
           return false;
        }
    });
}

Together with the created even you should have all the same possibilities of customization as if it would be easier possible to overwrite the method.

Upvotes: 1

PiTheNumber
PiTheNumber

Reputation: 23542

You should use events instead.

For example as closure:

protected static function booted(): void
{
    static::created(function (MyModel $myModel) {
        // ...
    });
}

Upvotes: 1

dparoli
dparoli

Reputation: 9161

The explanation is that the public static function create() is not defined in the Illuminate\Database\Eloquent\Model class.

Is handled as dynamic method call, that is is handled by calling the function:

public static function __callStatic($method, $parameters)

In the Illuminate\Database\Eloquent\Model class.

At the end the create() function is defined in the Illuminate\Database\Query\Builder class. That is the reason you cant override it in your Model and call parent::create()

IMHO I have not tested entirely, you could try with:

public static function create($attributes)
{
    return (new static)->newQuery()->create($attributes);
}

Upvotes: 9

Marcin Nabiałek
Marcin Nabiałek

Reputation: 111829

About errors, you should make sure you have enabled log_errors on your server. About the error, when you extend class and want to override method, it should have same signature, so it should be:

public static function create(array $attributes = [])
{
    // Your custom code goes here

    return parent::create($attributes);
}

(notice array type hinting). Obviously I assume you are going to add something more in this function :)

Upvotes: -2

Related Questions