Php 拉威尔在播种时口若悬河,毫无防备
我在雄辩方面遇到了一个奇怪的问题 我有两个雄辩的模型,一个用户模型和一个概要文件模型,它们都有单独的表,并且有一对一的关系 我有一个表单,其中两个模型的数据都被传递到其中。因此,表单中存在属于用户和配置文件的数据 我试图从控制器上尽可能干净地执行插入:Php 拉威尔在播种时口若悬河,毫无防备,php,laravel,orm,eloquent,laravel-artisan,Php,Laravel,Orm,Eloquent,Laravel Artisan,我在雄辩方面遇到了一个奇怪的问题 我有两个雄辩的模型,一个用户模型和一个概要文件模型,它们都有单独的表,并且有一对一的关系 我有一个表单,其中两个模型的数据都被传递到其中。因此,表单中存在属于用户和配置文件的数据 我试图从控制器上尽可能干净地执行插入: $user = $this->users->createUser($request->all()); createUser函数的定义如下 public function createUser(array $data) {
$user = $this->users->createUser($request->all());
createUser
函数的定义如下
public function createUser(array $data)
{
$user = new User($data);
// set some non relevant user options here...
$user->save();
$profile = new Profile($data);
$user->profile()->save($profile);
return $user;
}
但这会产生一个sql错误,因为eloquent将表单中的所有值分配给两个模型,因此User和Profile都会获得相同的属性,因此eloquent会尝试插入到给定模型不存在的列中
我以为$filleble
字段是用来防止这种情况发生的,但我在两种模型中都定义了$filleble
字段:
// User
protected $fillable = ['email', 'password', ...];
// Profile
protected $fillable = ['first_name', 'last_name', ...];
我也尝试过这样做:(新用户)->fill($data)
,但这不起作用,因为fill
方法也是从Model
构造函数调用的
在我看来,这不是预期的行为,但我可能再次误解了可填充的概念。如有任何见解,将不胜感激。我知道这可以通过声明我想发送给构造函数的每个键来解决,但这对我来说似乎非常混乱。此外,我正在使用laravel v5.2.29
编辑
经过进一步的测试,我得出结论,这只发生在我运行数据库种子程序的内部,在那里我确实使用了这些函数。深入挖掘,我发现这非常有意义,因为运行seed命令“unguards”是基本模型类。因此,这是预期的行为
我的问题是,有没有办法覆盖这个默认值,这样在运行seed命令时,模型就不会“不受保护”,这样我就可以使用助手函数来填充测试数据库,还是必须在seeder类中手动正确定义每个数据记录?是,从Laravel 5.2的某些版本中,当使用种子模型时,正如您所注意到的,这些模型是不设防的。事实上,这是很合理的,它是不设防的,但如果你想改变它,那么这是可能的,但不是那么简单 以下是实现这一目标的步骤:
config/app.php
lineillumb\Foundation\Providers\ConsoleSupportServiceProvider::class
中添加注释,添加自定义ConsoleSupportServiceProvider
类的添加行ConsoleSupportServiceProvider
相同的类(实际上您可以扩展它),但在$providers
属性中将illighted\Database\SeedServiceProvider
更改为自定义类SeedServiceProvider
的自定义SeedServiceProvider
,现在覆盖registerSeedCommand
以再次创建自定义SeedCommand
类SeedCommand
的自定义SeedCommand
类,现在只需更改:
public function fire()
{
if (! $this->confirmToProceed()) {
return;
}
$this->resolver->setDefaultConnection($this->getDatabase());
Model::unguarded(function () {
$this->getSeeder()->run();
});
}
进入
您的模型中有构造函数吗?您正在向用户和配置文件传递一个数组,请确保有一个构造函数用于处理它。用户和配置文件都继承自基本模型类,我不会重写构造函数。我已经缩小了问题的范围(见我的编辑),但不确定如何以干净的方式解决这个问题。为什么不去phpmyadmin或其他什么地方插入数据呢?这样做通常会破坏播种机的用途。谢谢你的澄清。在播种过程中数据库应该不受保护是有道理的,所以最后我改变了我的种子。我确实尝试实现我自己的Seed命令,但它不起作用,现在我明白了原因——我没有改变任何服务提供商。谢谢你的回答!
public function fire()
{
if (! $this->confirmToProceed()) {
return;
}
$this->resolver->setDefaultConnection($this->getDatabase());
$this->getSeeder()->run();
}