Carl-Tabuso's avatar

new Model()->getFillable()

i've been thinking about how eloquent’s getFillable() works.

normally, when defining a model i’ll either declare:

protected $fillable = [...attributes];

or

protected $guarded = [...attributes];

but if i only declare protected $guarded, calling getFillable() just returns an empty array.

looking at the method’s implementation, it seems like getFillable() only returns the fillable attributes if you explicitly define them in the $fillable array.

// /vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/GuardsAttributes.php

trait GuardsAttributes
{
    /**
     * Get the fillable attributes for the model.
     *
     * @return array<string>
     */
    public function getFillable()
    {
        return $this->fillable;
    }
}

i kinda expected eloquent to infer which attributes are fillable (especially since it’s able to figure it out when saving a model, even if i only declare one of either $fillable or $guarded).

so, shouldn’t getFillable() return the actual fillable attributes in this case, instead of just an empty array or this is some deliberate design decision of the framework that im missing? Thank you.

0 likes
2 replies
Glukinho's avatar

$guarded is opposite to $fillable.

So, if you have a table with fields id, name, description and model's fillable fields are id, name then logically guarded fields are the rest - only description field.

But since Laravel doesn't "know" a full set of model's fields (fields are stored as database table columns, not in a code) it can't determine $guarded based on known $fillable value (and vice versa).

That means, getFillable() can return only what you explicitly set for $fillable, it can't calculate fillable fields based on what you set on $guarded list.

kevinbui's avatar

It's cool to see people discuss Laravel source code and figure out how things works.

You probably has figured this out by now. I still give some answers anyway.

i kinda expected eloquent to infer which attributes are fillable (especially since it’s able to figure it out when saving a model, even if i only declare one of either $fillable or $guarded).

Laravel determines what attributes are fillable using the isFillable method, in the same trait.

so, shouldn’t getFillable() return the actual fillable attributes in this case, instead of just an empty array or this is some deliberate design decision of the framework that im missing?

The getFillable method should just return the $fillable property, because that property is protected.

Please or to participate in this conversation.