php - Laravel Eloquent 在播种期间无人看守

标签 php laravel orm eloquent laravel-artisan

我在 eloquent 方面遇到了一个奇怪的问题。

我有两个 Eloquent 模型,一个 User 模型和一个 Profile 模型,它们都有单独的表并且具有一对一的关系。

我有一个表单,其中传递了这两个模型的数据。因此属于 User 和 Profile 的数据出现在表单中。

我试图从 Controller 中尽可能干净地执行插入:

$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 会尝试插入给定模型不存在的列.

我以为 $fillable 字段是用来防止这种事情发生的,但我确实在两个模型中都定义了 $fillable 字段:

// User
protected $fillable = ['email', 'password', ...];

// Profile
protected $fillable = ['first_name', 'last_name', ...];

我也试过这个:(new User)->fill($data) 但这不起作用,也不应该,因为 fill 方法是也从 Model 构造函数中调用。

在我看来,这不是预期的行为,但话又说回来,我可能误解了可填充的概念。任何见解将不胜感激。我知道这可以通过声明我想发送给构造函数的每个键来解决,但这对我来说似乎很困惑。另外,我正在使用 laravel v5.2.29

编辑

经过进一步测试,我得出的结论是,这只会在我运行数据库播种器时在内部发生,我确实在其中使用了这些函数。深入挖掘,我发现这是完全合理的,因为运行 seed 命令“解除”了基本模型类。所以这是预期的行为。

我的问题是,有没有什么方法可以覆盖这个默认值,这样模型在运行 seed 命令时就不会“无人看守”,这样我就可以使用我的辅助函数来填充我的测试数据库,或者我必须在播种器类中手动正确定义每个数据记录?

最佳答案

是的,从某些版本的 Laravel 5.2 开始,当使用播种模型时,正如您所注意到的那样。其实不设防也是很合理的,但是如果你想改变它,也是可以的,但不是那么简单。

以下是您应该执行的步骤:

  1. config/app.phpIlluminate\Foundation\Providers\ConsoleSupportServiceProvider::class 中注释,添加自定义 ConsoleSupportServiceProvider 类。

  2. 创建与原始 ConsoleSupportServiceProvider 相同的类(实际上您可以扩展它)但是在 $providers 属性更改 Illuminate\Database\SeedServiceProvider 到自定义一个

  3. 再次创建扩展原始 SeedServiceProvider 的自定义 SeedServiceProvider,现在覆盖 registerSeedCommand 以再次创建自定义 SeedCommand 类(class)

  4. 创建扩展原始 SeedCommand 的自定义 SeedCommand 类,现在您只需要更改:

    public function fire()
    {
        if (! $this->confirmToProceed()) {
          return;
       }
    
       $this->resolver->setDefaultConnection($this->getDatabase());
    
       Model::unguarded(function () {
          $this->getSeeder()->run();
       });
    }
    

    进入

    public function fire()
    {
        if (! $this->confirmToProceed()) {
          return;
       }
    
       $this->resolver->setDefaultConnection($this->getDatabase());
    
       $this->getSeeder()->run();
    
    }
    

关于php - Laravel Eloquent 在播种期间无人看守,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36518036/

相关文章:

php - ie8中弹出窗口

php - mysql查询使用另一个查询的数组结果

javascript - 在另一个选择字段更改后重新填充的动态选择字段 - Laravel 5.2 和 JS

php - 教义 findOneBy 方法不起作用

mysql - 使用sqlalchemy过滤连接关系

javascript - 调用路由 URL 发送参数 CodeIgniter

php - 使用 php 在 html 页面中显示 bbcode

php - 如何解决 Laravel(IoC 容器)中的 BadMethodCallExeption

php - 如何从 laravel 中的表中选择所有列名?

node.js - Sequelize 默认排除