【问题标题】:Laravel 5.3 Eloquent updateOrCreateLaravel 5.3 Eloquent 更新或创建
【发布时间】:2017-12-19 15:24:25
【问题描述】:
try {
     \DB::beginTransaction();
      Model::updateOrCreate( ['id' => $id, 'number' => $number],
          ['value' => $request->get('value')]
      );
            \DB::commit();
     } catch (\Exception $e) {
            \DB::rollBack();
            throw new \Exception($e->error());
     }

我正在执行一项任务来创建一个通用特征,以防止多个用户同时更新记录。而且,我的方法是将 $data->updated_at 的隐藏输入放入刀片中,然后在发送更新请求时对其进行检查。并且在某些情况下,Laravel 的 updateOrCreate 用于更新或创建新记录。而且,我不知道该如何处理。我应该拆分创建和更新的方法还是有什么好的方法来处理它?

【问题讨论】:

  • 哪一部分给您带来了麻烦?
  • 问题是我无法使用 updateOrCreate 检查现有记录的更新日期,因为如果数据库中没有匹配项,它只会创建一条新记录。项目中有多个 updateOrCreate 方法,所以我想知道是否可以保留该方法并防止多个用户同时更新现有数据。抱歉,我猜我的问题不太清楚
  • 您应该将更新并创建为两个单独的端点然后在进行更新时检查它是否存在,如果存在,请更新它。
  • @Jasurbek 谢谢,现在更清楚了:)。你自己回答了一部分。如果您出于提到的原因想要包含该字段,则不能像这样使用updateOrCreate。顺便说一句updateOrCreate 基本上是这样的:firstOrNew($attributes)->fill($values)->save()
  • @DevinGray 似乎这是我想要在那里实现的唯一途径。

标签: php laravel eloquent


【解决方案1】:

你可能想把你正在做的事情分开。

我在玩,想出了这个有趣(尚未测试):

Illuminate\Database\Eloquent\Builder::macro('createOrUpdateWhen', function ($attributes = [], $values = [], $when = null) {
    $m = $this->firstOrNew($attributes);

    if (is_array($when)) {
        $when = function ($m) use ($when) {
            foreach ($when as $key => $value) {
                if ($m->$key != $value) {
                    return false;
                }
            }

            return true;
        }
    }

    if (! $m->exists || $when($m)) {
        $m->fill($values);
    }

    $m->save();

    return $m;
});

$m = M::createOrUpdateWhen($attributes, $values, function ($m) use ($request) {
    return $m->updated_at == $request->input('updated_at');
});

$m = M::createOrUpdateWhen(
    $attributes, $values, ['updated_at' => $request->input('updated_at')]
);

:-}

【讨论】:

  • 感谢您的时间和代码。我已经通过分离更新和创建完成了任务。顺便说一句,是否可以在 Laravel 5.3 上使用宏功能?
  • 奇怪的是,Eloquent Builder 在 5.3 中确实有一个 macro 方法,但它不是这样静态的,所以这不会以这种方式工作......这已经在新版本中进行了调整......我如果可以的话,强烈建议升级到 5.5 LTS,还有很多其他原因
【解决方案2】:
    $post = Model::where([['id', $id], ['number', $number]])->first();
    try {
        \DB::beginTransaction();
        if (is_null($post)) {
            Model::create($input);
        } else {
            $post->updateWithExclLock($request->get('updated_at'), $input]);
        }

【讨论】:

    猜你喜欢
    • 2017-05-10
    • 1970-01-01
    • 2013-09-21
    • 2018-10-29
    • 2014-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多