为啥 eloquent 不会在不同的主键上返回错误?

Posted

技术标签:

【中文标题】为啥 eloquent 不会在不同的主键上返回错误?【英文标题】:Why eloquent doesn't return error on diffrent primarykey?为什么 eloquent 不会在不同的主键上返回错误? 【发布时间】:2018-06-21 14:53:49 【问题描述】:

我正在研究一个主键为“Id”的旧数据库。 Eloquent 将主键设置为默认的 'id',因此变化不大,但仍然可能令人困惑。当然我没有注意到这一点,我想将更新的模型保存到数据库中。没有错误,$model->save() 返回很好但是数据库没有更新。此外,我还有其他从数据库中获取模型的函数,它们可以正常工作而不会覆盖$primarykey

所以这是我的问题:为什么 eloquent 不返回任何警告或错误?当然,我在文档中发现我应该在模型中覆盖$primarykey,然后一切正常。

我使用的是 mysql 10.1.16-MariaDB。 这是 Laravel 控制器

 public function update(Request $request, Order $order)
     
        $order->fill($request->get('data'));
        $order->save();
        $order->products;
        return $order;
     

Vue.js 函数

editOrder () 
    this.fullscreenLoading = true
    axios.put('/web/' + this.url + '/' + this.rowId, 'data': this.row)
      .then((data) => 
        this.row = data;
        this.fullscreenLoading = false
      );
  ,

Laravel 模型是标准的,当然我的模型现在已经正确更新了,当我遇到这个问题时,没有 $primarykey,我没有提到 $fillable 以及与产品的关系,但在我的项目中它们已定义并正常工作。

class Order extends Model
   
      use LogsActivity;
      protected $table = 'orders';
      protected $primaryKey = 'Id';
      protected $fillable = []
   

【问题讨论】:

我已经在下面回答了您的问题,但是如果您需要一些特定查询的帮助,请出示代码。 如果你保存时没有指定主键,那么 laravel 应该假设“id”是主键。如果您也不包含“id”参数,那么“save”应该在每次保存时创建一个全新的行,并且不会返回任何错误,因为一切正常。这不是正在发生的事情吗,每次保存时都会显示不同的行? @Amarnasan 保存后没有全新的行和数据库根本没有改变 除非你以某种方式更改了 PDO::ATTR_ERRMODE 选项,否则如果数据库返回错误,Laravel 会抛出异常。但是,如果您想要更具体的答案,则需要提供更多信息。例如,显示您的代码,提及您正在使用的数据库,显示您如何确定您的语句已运行但数据库未更新... @patricus 我用用于生成此问题的代码编辑了我的问题 【参考方案1】:

如果您使用get()create() 或类似方法执行查询,它将像以前一样工作,因为在这种情况下 Eloquent 不使用 PK。但是在模型中设置$primaryKey 属性之前,find() 等一些方法对您不起作用。

【讨论】:

感谢您的回答,我解决了我的问题,但我想从 eloquent 的底层了解它是如何工作的。我认为当保存未正确执行时,elqouent 可能会发出警告或错误。我知道这在文档中有所描述,但仍然可以告知。【参考方案2】:

您没有收到错误,因为没有错误。

当您运行 $order->save() 时,生成的查询将类似于:

update `orders` set `field1` = ?, `fieldN` = ?, `updated_at` = ? where `id` is null

这是一个完全有效的 SQL 语句,当它运行时,它不会产生任何错误。但是,它也不会更新任何记录(除非您确实有 id 为空的记录)。

更新查询使用null的原因是因为你的Order模型没有id属性,它有Id属性,而且php数组键是区分大小写的。因此,当 Laravel 尝试获取 id 属性的值时,它会返回 null,并在查询中使用它。

【讨论】:

以上是关于为啥 eloquent 不会在不同的主键上返回错误?的主要内容,如果未能解决你的问题,请参考以下文章

在 Oracle SQL 的主键上声明附加索引时会发生啥?

在cassandra的主键上匹配'like'的模式

为啥主键上的“order by”会更改查询计划,从而忽略有用的索引?

在主键上使用 If Not Exists

外键为啥不一定与相应的主键重名

我需要在 Oracle 的外键上创建索引吗?