phplaraveleloquent

Eloquent ORM: Define allowed model attributes


In Laravel's Eloquent ORM, is there a way to define a model's allowed attributes?

By default I can put any attributes into the model's constructor - but then I only get notified about the erroneous attribute names when I actually try to save the model to database.

Example code:

// this works although there is a typo in "lastname"
$user = new \App\User(['firstname' => 'foo', 'lastnam' => 'bar']);

// this errors out with an SQL error
$user->save();

So, is there a way to let Laravel automatically check if there are invalid keys in the request's input data?


Solution

  • If you would like to prevent not only filling not allowed attributes using fill() method but also directly setting them, like $model->foo = 'bar', then you got to override Model::setAttribute() method.

    Best to do it in a custom base Model that extends Eloquent. So in app/Model.php:

    namespace App;
    
    use Exception;
    use Illuminate\Database\Eloquent\Model as Eloquent;
    
    class Model extends Eloquent
    {
        // this should be actually defined in each sub-model
        protected $allowed = ['firstname', 'lastname'];
    
        public function setAttribute($key, $value)
        {
            // this way we can allow some attributes by default
            $allowed = array_merge($this->allowed, ['id']);
    
            if (! in_array($key, $allowed)) {
                throw new Exception("Not allowed attribute '$key'.");
            }
    
            return parent::setAttribute($key, $value);
        }
    }
    

    Then in the models that should not allow invalid attributes you can extend this base model:

    use App\Model;
    
    class User extends Model