8
votes

I'm using Eloquent models within Laravel 5.4 In the documentation, I see:

You may also use the create method to save a new model in a single line. The inserted model instance will be returned to you from the method. However, before doing so, you will need to specify either a fillable or guarded attribute on the model, as all Eloquent models protect against mass-assignment by default.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Flight extends Model
{
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['name'];
}

However, the $fillable property is already defined in a trait used by all models:

trait GuardsAttributes
{
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [];

...

The PHP documentation is clear about Traits properties:

If a trait defines a property then a class can not define a property with the same name, otherwise an error is issued. It is an E_STRICT if the class definition is compatible (same visibility and initial value) or fatal error otherwise.

Is the Laravel documentation wrong about the adivsed implementation?

1
Neither are wrong. You have class A and you use a trait inside that class. Trait = language assisted copy paste. Class A can't contain protected $fillable - and it doesn't, because your class A is Illuminate\Database\Eloquent\Model. So far so good - but now you are extending the Model and you can override the protected $fillable property. Inheritance rules allow for this. Your question is valid, but so are both excerpts from documentation.Mjh

1 Answers

10
votes

You cannot override trait properties in the same class as the PHP documentation suggests.

Laravel, however, is asking you to override this in a child class (your model class which extends the Eloquent model class and the trait is included in the Eloquent model class, not your model class). This is a perfectly valid thing to do!