Laravel中的MassAssignmentException

use*_*060 101 php laravel

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

  [Illuminate\Database\Eloquent\MassAssignmentException]
  username



db:seed [--class[="..."]] [--database[="..."]]
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么.我使用的命令是:

php artisan db:seed --class="UsersTableSeeder"
Run Code Online (Sandbox Code Playgroud)

我的种子课如下:

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'
            ]);
    }
}
Run Code Online (Sandbox Code Playgroud)

Ale*_*ski 223

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

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

class User extends Model
{
    protected $fillable = ['username', 'email', 'password'];
}
Run Code Online (Sandbox Code Playgroud)

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

  • -1虽然这个工程,从Pascalculator的解决方案是因为它未卫士为应用程序的生命周期需要更好的质量,分配,只有当不能及的. (7认同)
  • 我保留我的答案,因为我认为这是一个很好的通用模式(我在我的项目中使用它),因为我认为它不是或多或少符合Laravel约定而不是你的答案(参见文档).但是,因为多个意见很好,而且因为你的解决方案可以和我的一样好,所以我赞成它,我鼓励其他人阅读它:) (4认同)

Pas*_*tor 29

我正在使用Laravel 4.2.

你看到的错误

[Illuminate\Database\Eloquent\MassAssignmentException]
username
Run Code Online (Sandbox Code Playgroud)

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

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

class DatabaseSeeder extends Seeder {

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

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

        //$this->call('UserTableSeeder');
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

  • 对于偏执狂和纯粹主义者:在你的批量分配完成后,你也会发现使用`\ Eloquent :: reguard();`. (3认同)

bic*_*cle 7

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

通常这已经在DatabaseSeeder类中指定.但是因为你UsersTableSeeder直接打电话:

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

Eloquent::unguard(); 没有被调用并给出错误.


Tia*_*vêa 6

要使所有字段都可填写,只需在您的班级上声明:

protected $guarded = array();
Run Code Online (Sandbox Code Playgroud)

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


par*_*ini 5

我用过这个,没有问题:

protected $guarded=[];
Run Code Online (Sandbox Code Playgroud)