Laravel - 表没有主键=在执行保存时更新所有记录

时间:2017-10-25 09:28:21

标签: php laravel laravel-5

致力于传承' Lavaral项目有一些数据库结构问题。

有一个数据透视表,用于将服务链接到用户。问题是桌面上没有主键。相反,它具有以下内容:

id (relates to service_id)
user_id
duration
price

问题是,在更新单个用户服务信息时,它实际上正在更新数据库中id(service_id)相同的每条记录。

示例:2个用户在数据库中具有以下内容

id = 1, user_id = 1, duration = null, price = null
id = 1, user_id = 2, duration = null, price = null

服务标识1引用服务表中记录的ID。

有一个模式为用户执行API调用以更新特定服务,此端点(精简)如下所示:

foreach ($request->services as $key => $value) {
    $serviceRecord = ServiceUser::where('user_id', $userId)->where('id', $value['id'])->first();

    $serviceRecord->duration = ($value['duration'] ? $value['duration'] : null);
    $serviceRecord->price = ($value['price'] ? $value['price'] : null);
    $serviceRecord->save();
}

目前正在使用相同的价格/期限信息更新两个用户记录。

我的问题是,现在这是一个非常大的项目,并且对ServiceUser的id字段有无数的引用。有没有办法使这个保存只更新执行first()方法时返回的记录?或者我是否需要浏览整个应用程序并更改它以便它使用此表的主键?

1 个答案:

答案 0 :(得分:1)

Laravel的罪魁祸首是Illuminate\Database\Eloquent\Model中的这种方法:

/**
 * Set the keys for a save update query.
 *
 * @param  \Illuminate\Database\Eloquent\Builder  $query
 * @return \Illuminate\Database\Eloquent\Builder
 */
protected function setKeysForSaveQuery(Builder $query)
{
    $query->where($this->getKeyName(), '=', $this->getKeyForSaveQuery());
    return $query;
}

这基本上将保存查询范围限定为模型的主键。但是,由于您的模型没有定义任何唯一键,因此它会相应地更新所有适用的记录,即使您只使用变量中的一个模型也是如此。

由于没有真正解决这种Eloquent耦合行为的方法,我建议您采用“简单的旧”方式进行数据库调用:

$serviceUser = new ServiceUser;

DB::table($serviceUser->getTable())
  ->where('user_id', $userId)
  ->where('id', $value['id'])
  ->limit(1) // This limits to only the first encountered row
  ->update([
      'duration' => ($value['duration'] ? $value['duration'] : null),
      'price' => ($value['price'] ? $value['price'] : null),
  ]);
祝你好运!

(免责声明:我没有测试代码,所以它可能会受到错别字的影响;要点很重要)