MassAssignmentException in Laravel

PhpLaravel

Php Problem Overview


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'
            ]);
	}
}

Php Solutions


Solution 1 - Php

Read this section of Laravel doc : http://laravel.com/docs/eloquent#mass-assignment

Laravel provides by default a protection against mass assignment security issues. That's why you have to manually define which fields could be "mass assigned" :

class User extends Model
{
    protected $fillable = ['username', 'email', 'password'];
}

Warning : be careful when you allow the mass assignment of critical fields like password or role. It could lead to a security issue because users could be able to update this fields values when you don't want to.

Solution 2 - Php

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.

Solution 3 - Php

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.

Solution 4 - Php

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.

Solution 5 - Php

I used this and have no problem:

protected $guarded=[];

Solution 6 - Php

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

Solution 7 - Php

User proper model in your controller file.

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

Solution 8 - Php

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

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

Solution 9 - Php

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.

Solution 10 - Php

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);

Solution 11 - Php

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();

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser1801060View Question on Stackoverflow
Solution 1 - PhpAlexandre ButynskiView Answer on Stackoverflow
Solution 2 - PhpPascalculatorView Answer on Stackoverflow
Solution 3 - PhpTiago GouvêaView Answer on Stackoverflow
Solution 4 - PhpbicycleView Answer on Stackoverflow
Solution 5 - PhpparastooView Answer on Stackoverflow
Solution 6 - PhpAmit GargView Answer on Stackoverflow
Solution 7 - PhpRahul HirveView Answer on Stackoverflow
Solution 8 - PhpDolDurmaView Answer on Stackoverflow
Solution 9 - PhpSameer ShaikhView Answer on Stackoverflow
Solution 10 - PhpAminView Answer on Stackoverflow
Solution 11 - PhpMark Shust at M.academyView Answer on Stackoverflow