MassassignmentException在Laravel中
我是Laravel的新手。 我想种子我的数据库。 当我运行种子命令时,我得到一个exception
[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' ]); } }
阅读Laravel文档的这一部分: http ://laravel.com/docs/eloquent#mass-assignment
Laravel默认提供防范大规模分配安全问题的保护。 这就是为什么你必须手动定义哪些字段可以被“批量分配”:
class User extends Model { protected $fillable = ['username', 'email', 'password']; }
警告:当您允许批量分配password
或role
等重要字段时,请小心。 这可能会导致安全问题,因为用户可以在不需要时更新此字段值。
我正在使用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。
另请注意 ,您正在使用复数类名Users,而Laraval使用单数formsUser。 如果您决定将您的类更改为常规单数forms,则可以简单地取消注释//$this->call('UserTableSeeder');
它已经被分配,但是在DatabaseSeeder类中被默认注释掉了。
只需添加Eloquent::unguard();
在运行方法的顶部,当你做一个种子时,不需要在所有你需要种子的模型中创build一个$fillable
数组。
通常这已经在DatabaseSeeder
类中指定。 但是,因为您直接调用UsersTableSeeder
:
php artisan db:seed --class="UsersTableSeeder"
Eloquent::unguard();
没有被调用,并给出错误。
为了使所有字段可填写 ,只需在你的类上声明:
protected $guarded = array();
这将使您可以调用填充方法,而无需声明每个字段。
当我像这样扩展我的模型时,我遇到了MassAssignmentException。
class Upload extends Eloquent { }
我试图像这样插入数组
Upload::create($array);//$array was data to insert.
当我创build上传模型为问题已解决
class Upload extends Eloquent { protected $guarded = array(); // Important }
参考https://github.com/aidkit/aidkit/issues/2#issuecomment-21055670
如果你有数据库上的表和字段,你可以简单地使用这个命令:
php artisan db:seed --class=UsersTableSeeder --database=YOURDATABSE
使用可填充来告诉laravel可以使用数组填充哪些字段。 默认情况下,laravel不允许通过数组更新数据库字段
受保护的$ fillable = array('你想用数组填充的字段');
可填写的对面是可以防范的。
当你想播种数据库时,这不是一个好方法。
使用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);
我用这个,没有问题:
protected $guarded=[];
如果使用OOP插入方法,则不需要担心批量操作/可填充属性:
$user = new User; $user->username = 'Stevo'; $user->email = 'steve@rute.co.za'; $user->password = '45678'; $user->save();