【问题标题】:Laravel 8.x - How to use updateOrCreate with a where clause?Laravel 8.x - 如何使用带有 where 子句的 updateOrCreate?
【发布时间】:2021-11-26 03:05:48
【问题描述】:

我正在尝试使用 Laravel updateOrCreate 根据 ID 是否存在来更新本月和上个月的记录。

\App\Models\Result::updateOrCreate(
        [
            'id' => $request->get('id'),
            // where created_at is within the last 2 months
            'created_at' => [
                '>',
                \Carbon\Carbon::now()->startOfMonth()->subMonthsNoOverflow()
            ],
        ],
        [
            'discipline_one' => $request->get('d-one'),
            'discipline_two' => $request->get('d-two'),
            'discipline_three' => $request->get('d-three'),
            'discipline_four' => $request->get('d-four'),
            'discipline_five' => $request->get('d-five'),
            'discipline_six' => $request->get('d-six'),
        ]
    );

如果 ID 存在,并且结果在当前月份或上个月,则创建新记录而不是更新记录。

预期输入:1(从上个月开始存在)
预期输出:记录已更新

预期输入:2(不存在或不在 2 个月内)
预期输出:创建新记录

更新:

使用建议的答案,

'id' => $request->get('id'),
'created_at' => \App\Models\Result::whereBetween('created_at', [
    \Carbon\Carbon::now()->startOfMonth()->subMonthsNoOverflow(),
    \Carbon\Carbon::now()->endOfMonth(),
]),

我得到错误:

Illuminate\Database\Eloquent\Builder 类的对象无法转换为字符串

【问题讨论】:

    标签: php laravel laravel-8


    【解决方案1】:

    给你:

    您只需要显式在方法的第一个参数中定义操作符

    方法的第一个参数中数组的每个元素都应该是一个包含三个参数的数组。
    列、运算符、值

    $startDate = \Carbon\Carbon::now()->startOfMonth()->subMonths(2);
    $endDate = \Carbon\Carbon::now()->endOfMonth();
    
    $resultRow = \App\Models\Result::query()
            ->where('id', $request->id)
            ->whereBetween('created_at', [$startDate, $endDate])
            ->first();
    
    \App\Models\Result::updateOrCreate(
        [
            [
                'id', '=', $request->get('id'),
            ],
            [
                'created_at', '>=', $startDate,
            ],
            [
                'created_at', '<=', $endDate,
            ],
        ],
    
        array_merge(
            [
                'discipline_one' => $request->get('d-one'),
                'discipline_two' => $request->get('d-two'),
                'discipline_three' => $request->get('d-three'),
                'discipline_four' => $request->get('d-four'),
                'discipline_five' => $request->get('d-five'),
                'discipline_six' => $request->get('d-six'),
            ],
    
            $resultRow ? [] : [
                'id' => $request->get('id'),
                'created_at' => \Carbon\Carbon::now()
            ]
        )
    
    );
    

    请注意,我在方法的第二个参数中重复了idcreated_at 列设置。这是因为与常规行为相反,如果没有找到符合该标准的结果,则不会根据我的测试执行 2 方法的参数数组的合并。

    【讨论】:

    • Laravel 有一个全局辅助函数 now() 很长时间了。您应该先进行日期减法,然后使用月初。例如。 now()-&gt;subMonths(2)-&gt;startOfMonth().
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-05
    • 2015-09-05
    • 2015-05-23
    相关资源
    最近更新 更多