Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MassAssignmentException in Laravel

Tags:

php

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'
            ]);
    }
}
like image 961
user1801060 Avatar asked Mar 09 '14 08:03

user1801060


3 Answers

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.

like image 164
Alexandre Butynski Avatar answered Nov 07 '22 20:11

Alexandre Butynski


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.

like image 20
Pascalculator Avatar answered Nov 07 '22 20:11

Pascalculator


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.

like image 11
Tiago Gouvêa Avatar answered Nov 07 '22 21:11

Tiago Gouvêa