[php] MassAssignmentException in Laravel

I am a Laravel newbie. I want to seed my database. When I run the seed command I get an exception

  [Illuminate\Database\Eloquent\MassAssignmentException]
  username



db:seed [--class[="..."]] [--database[="..."]]

What am I doing wrong. The command I use is:

php artisan db:seed --class="UsersTableSeeder"

My seed class is as follows:

class UsersTableSeeder extends Seeder {
    public function run()
    {
            User::truncate();
            User::create([
                'username' => 'PaulSheer',
                'email' => '[email protected]',
                'password' => '45678'
            ]);

            User::create([
                'username' => 'Stevo',
                'email' => '[email protected]',
                'password' => '45678'
            ]);
    }
}

This question is related to php laravel

The answer is


I was getting the MassAssignmentException when I have extends my model like this.

class Upload extends Eloquent {

}

I was trying to insert array like this

Upload::create($array);//$array was data to insert.

Issue has been resolve when I created Upload Model as

class Upload extends Eloquent {
    protected $guarded = array();  // Important
}

Reference https://github.com/aidkit/aidkit/issues/2#issuecomment-21055670


if you have table and fields on database you can simply use this command :

php artisan db:seed --class=UsersTableSeeder --database=YOURDATABSE

Just add Eloquent::unguard(); in the top of the run method when you do a seed, no need to create an $fillable array in all the models you have to seed.

Normally this is already specified in the DatabaseSeeder class. However because you're calling the UsersTableSeeder directly:

php artisan db:seed --class="UsersTableSeeder"

Eloquent::unguard(); isn't being called and gives the error.


This is not a good way when you want to seeding database.
Use faker instead of hard coding, and before all this maybe it's better to truncate tables.

Consider this example :

    // Truncate table.  
    DB::table('users')->truncate();

    // Create an instance of faker.
    $faker = Faker::create();

    // define an array for fake data.
    $users = [];

    // Make an array of 500 users with faker.
    foreach (range(1, 500) as $index)
    {
        $users[] = [
            'group_id' => rand(1, 3),
            'name' => $faker->name,
            'company' => $faker->company,
            'email' => $faker->email,
            'phone' => $faker->phoneNumber,
            'address' => "{$faker->streetName} {$faker->postCode} {$faker->city}",
            'about' => $faker->sentence($nbWords = 20, $variableNbWords = true),
            'created_at' => new DateTime,
            'updated_at' => new DateTime,
        ];
    }

    // Insert into database.
    DB::table('users')->insert($users);

If you use the OOP method of inserting, you don't need to worry about mass-action/fillable properties:

$user = new User;
$user->username = 'Stevo';
$user->email = '[email protected]';
$user->password = '45678';
$user->save();

I am using Laravel 4.2.

the error you are seeing

[Illuminate\Database\Eloquent\MassAssignmentException]
username

indeed is because the database is protected from filling en masse, which is what you are doing when you are executing a seeder. However, in my opinion, it's not necessary (and might be insecure) to declare which fields should be fillable in your model if you only need to execute a seeder.

In your seeding folder you have the DatabaseSeeder class:

class DatabaseSeeder extends Seeder {

    /**
    * Run the database seeds.
    *
    * @return void
    */

    public function run()
    {
        Eloquent::unguard();

        //$this->call('UserTableSeeder');
    }
}

This class acts as a facade, listing all the seeders that need to be executed. If you call the UsersTableSeeder seeder manually through artisan, like you did with the php artisan db:seed --class="UsersTableSeeder" command, you bypass this DatabaseSeeder class.

In this DatabaseSeeder class the command Eloquent::unguard(); allows temporary mass assignment on all tables, which is exactly what you need when you are seeding a database. This unguard method is only executed when you run the php aristan db:seed command, hence it being temporary as opposed to making the fields fillable in your model (as stated in the accepted and other answers).

All you need to do is add the $this->call('UsersTableSeeder'); to the run method in the DatabaseSeeder class and run php aristan db:seed in your CLI which by default will execute DatabaseSeeder.

Also note that you are using a plural classname Users, while Laraval uses the the singular form User. If you decide to change your class to the conventional singular form, you can simply uncomment the //$this->call('UserTableSeeder'); which has already been assigned but commented out by default in the DatabaseSeeder class.


To make all fields fillable, just declare on your class:

protected $guarded = array();

This will enable you to call fill method without declare each field.


I used this and have no problem:

protected $guarded=[];

Use the fillable to tell laravel which fields can be filled using an array. By default, Laravel does not allow database fields to be updated via an array

Protected $fillable=array('Fields you want to fill using array');

The opposite of fillable is guardable.


User proper model in your controller file.

<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\User;