Laravel中的MassAssignmentException

时间:2014-03-09 08:39:58

标签: php laravel

我是Laravel的新手。我想种下我的数据库。当我运行种子命令时,我得到一个异常

  [Illuminate\Database\Eloquent\MassAssignmentException]
  username



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

我做错了什么。我使用的命令是:

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

我的种子课程如下:

class UsersTableSeeder extends Seeder {
    public function run()
    {
            User::truncate();
            User::create([
                'username' => 'PaulSheer',
                'email' => 'psheer@rute.co.za',
                'password' => '45678'
            ]);

            User::create([
                'username' => 'Stevo',
                'email' => 'steve@rute.co.za',
                'password' => '45678'
            ]);
    }
}

11 个答案:

答案 0 :(得分:215)

阅读Laravel文档的这一部分:http://laravel.com/docs/eloquent#mass-assignment

Laravel默认提供针对质量分配安全问题的保护。这就是为什么你必须手动定义哪些字段可以“批量分配”:

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

警告:在允许批量分配passwordrole等关键字段时要小心。这可能会导致安全问题,因为用户可以在您不想更新时更新此字段值。

答案 1 :(得分:29)

我正在使用Laravel 4.2。

您看到的错误

[Illuminate\Database\Eloquent\MassAssignmentException]
username

确实是因为数据库受到保护而不会集体填充,这是您在执行播种器时正在执行的操作。但是,在我看来,如果你只需要执行一个播种机,那么声明哪些字段应该在你的模型中可填写是没有必要的(也可能是不安全的)。

在您的种子文件夹中,您拥有DatabaseSeeder类:

class DatabaseSeeder extends Seeder {

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

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

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

此类充当外观,列出了需要执行的所有播种器。如果您通过artisan手动调用UsersTableSeeder播种器,就像使用php artisan db:seed --class="UsersTableSeeder"命令一样,则绕过此DatabaseSeeder类。

在此DatabaseSeeder类中,命令Eloquent::unguard();允许在所有表上进行临时批量分配,这正是您为种子数据库播种时所需的内容。这种unguard方法仅在您运行php aristan db:seed命令时执行,因此它是临时的,而不是使您的模型中的字段可填写(如接受和其他答案中所述)。

您需要做的就是将$this->call('UsersTableSeeder');添加到DatabaseSeeder类中的run方法,并在CLI中运行php aristan db:seed,默认情况下将执行DatabaseSeeder。

另请注意您使用的是复数类名用户,而Laraval使用单数形式的用户。如果您决定将类更改为常规单数形式,则可以取消注释已经分配但在DatabaseSeeder类中默认注释掉的//$this->call('UserTableSeeder');

答案 2 :(得分:7)

在执行种子时,只需在run方法的顶部添加Eloquent::unguard();,无需在所有必须种子的模型中创建$fillable数组。

通常这已在DatabaseSeeder类中指定。但是因为您直接呼叫UsersTableSeeder

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

Eloquent::unguard();未被调用并给出错误。

答案 3 :(得分:6)

要使所有字段都可填写,只需在您的课程中声明:

protected $guarded = array();

这将使您能够在不声明每个字段的情况下调用fill方法。

答案 4 :(得分:3)

我用过这个并没有问题:

protected $guarded=[];

答案 5 :(得分:1)

当我像这样扩展我的模型时,我得到了MassAssignmentException。

class Upload extends Eloquent {

}

我试图像这样插入数组

Upload::create($array);//$array was data to insert.
当我将上传模型创建为

时,

问题已解决

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

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

答案 6 :(得分:1)

控制器文件中的用户正确模型。

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

答案 7 :(得分:0)

如果您在数据库中有表和字段,则只需使用以下命令:

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

答案 8 :(得分:0)

使用可填写告诉laravel可以使用数组填充哪些字段。 默认情况下,Laravel不允许通过数组

更新数据库字段
Protected $fillable=array('Fields you want to fill using array');

可填写相反的是可保护

答案 9 :(得分:0)

当你想播种数据库时,这不是一个好方法。
使用faker而不是硬编码,在此之前,最好截断表格。

考虑这个例子:

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

答案 10 :(得分:-1)

如果您使用OOP插入方法,则无需担心质量操作/可填充属性:

$user = new User;
$user->username = 'Stevo';
$user->email = 'steve@rute.co.za';
$user->password = '45678';
$user->save();