为什么我的 Eloquent 模型在升级到 Laravel 8 后没有保存?

Why aren't my Eloquent models saving after upgrading to Laravel 8?

需要一些帮助摆脱杂草。我有一个 Laravel 应用程序,它从 4.2 开始一直到现在,我每两年升级一次并跳版本。我白天是一名 .NET 开发人员,但仍在继续维护此应用程序。无论如何...

我从 Laravel 6.x 升级到 8.x,并开始使用 Docker。我将所有内容都部署到我的生产环境中,并且大部分都在运行。我做了一些简单的测试,诚然我没有对所有的东西进行测试,但代码的一些随机部分实际上并没有将记录保存到数据库中。这太奇怪了。几天来我一直在进行故障排除,这就是我在这一点上着陆的地方:

  1. Laravel 8
  2. MariaDB
  3. Laravel Sail 托管开发环境
  4. Tinker 让我 created/updated/delete 使用 Eloquent
  5. 记录没有问题
  6. 有些东西正在生产环境中保存(这是使用MySql)

您可能想知道数据库的差异,我使用的是 M1 Mac 并且 M1 尚不支持 MySql Docker 图像。据我了解,Mariadb 是一个直接替代品。

这是我今晚写的代码,试图简化我 6-7 年前写的一些非常古老的意大利面条代码……现在并没有好多少,但请放轻松。最终,只有 4 个数组来自我正在迭代的 Angular 前端和 creating/updating 记录,然后将所有内容传递回浏览器。

我想不通的是它都说它保存了,它增加了数据库表中的 PK,我用新分配的 PK 得到了完全形成的模型......但它只是没有' 保存在数据库中。所有的失败都是完全无声的,我没有发现任何日志,在 vscode 中使用 xdebug 调试时没有问题,没有 sql 日志,Eloquent 模型表示它是否成功 create/update。是的,似乎没有任何保存。

但我可以获取所有完全相同的数据,然后 运行 将其保存在 tinker 中,并且保存得非常好……我真的对我所缺少的东西感到困惑。在 400 人对我的 eloquent 模型 class 中的 $primaryKey 属性 作出回应之前,我肯定已经检查了这些一百万次(或者至少这是它的感觉就像现在一样)。

/**
     * Replaces UploadInvoice()
     * Saves from editing an invoice.
     *
     * @param Request $request
     *
     * @return JsonResponse
     */
    public function saveApiInvoice(Request $request): JsonResponse
    {
        $result = new OpResult();
        DB::beginTransaction();

        try {
            $this->deletePendingInvoiceItems($request['pendingDeletes']);
            $sales = $this->saveSaleRecords($request)->getData();
            $overrides = $this->saveOverrideRecords($request)->getData();
            $expenses = $this->saveExpenseRecords($request)->getData();

            $payroll = $this->savePayrollInfo($request, $sales, $overrides, $expenses)->getData();

            $this->paystubService->processPaystubJob($request['issueDate']);

            return $result->setData([
                'sales' => $sales,
                'overrides' => $overrides,
                'expenses' => $expenses,
                'payroll' => $payroll
            ])->getResponse();
            
        } catch (\Exception $ex) {
            DB::rollBack();

            return $result->setToFail($ex)
                ->getResponse();
        }
    }

private function savePayrollInfo($request, $sales, $overrides, $expenses)
    {
        $result = new OpResult();
        $total = 0;

        foreach ($sales as $sale) {
            $total += $sale['amount'];
        }

        foreach ($overrides as $override) {
            $total += $override['total'];
        }

        foreach ($expenses as $expense) {
            $total += $expense['amount'];
        }

        $payroll = Payroll::agentId($request['agentid'])
            ->vendor($request['vendorId'])
            ->payDate($request['issueDate'])
            ->first();

        if ($payroll != null) {
            $payroll->amount = $total;
        } else {
            $agent = Employee::find($request['agentid']);

            $payroll = new Payroll([
                'agent_id' => $request['agentId'],
                'agent_name' => $agent != null ? $agent->name : '',
                'amount' => $total,
                'is_paid' => false,
                'vendor_id' => $request['vendorId'],
                'pay_date' => $request['issueDate']
            ]);
        }

        $saved = $payroll->save();

        return $result->setStatus($saved)
            ->setDataOnSuccess($payroll);
    }

    private function saveExpenseRecords($request)
    {
        $result = new OpResult();
        $expenses = [];

        foreach ($request['expenses'] as $e) {
            $expense = new Expense([
                'vendor_id' => $request['vendorId'],
                'type' => $e['type'],
                'notes' => $e['notes'],
                'amount' => is_numeric($e['amount']) ? $e['amount'] + 0 : 0,
                'agentid' => $request['agentId'],
                'issue_date' => $request['issueDate'],
                'wkending' => $request['weekending']
            ]);

            $save_success = $expense->save();

            if ($save_success) {
                $expenses[] = $expense;
            }
        }

        return $result->setDataOnSuccess($expenses);
    }

    private function saveOverrideRecords($request)
    {
        $result = new OpResult();
        $overrides = [];

        foreach ($request['overrides'] as $o) {
            $override = new Override([
                'vendor_id' => $request['vendorId'],
                'name' => $o['name'],
                'sales' => $o['sales'],
                'commission' => is_numeric($o['commission']) ? $o['commission'] + 0 : 0,
                'total' => is_numeric($o['total']) ? $o['total'] + 0 : 0,
                'agentid' => $request['agentId'],
                'issue_date' => $request['issueDate'],
                'wkending' => $request['weekending']
            ]);

            $save_success = $override->save();

            if ($save_success) {
                $overrides[] = $override;
            }
        }

        return $result->setDataOnSuccess($overrides);
    }

    private function saveSaleRecords($request)
    {
        $result = new OpResult();

        $sales = [];
        foreach ($request['sales'] as $invoice) {
            $sale = new Invoice([
                'vendor' => $request['vendorId'],
                'sale_date' => Carbon::parse($invoice['saleDate'])->format('Y-m-d'),
                'first_name' => $invoice['firstName'],
                'last_name' => $invoice['lastName'],
                'address' => $invoice['address'],
                'city' => $invoice['city'],
                'status' => $invoice['status'],
                'amount' => is_numeric($invoice['amount']) ? $invoice['amount'] + 0 : 0,
                'agentid' => $request['agentId'],
                'issue_date' => $request['issueDate'],
                'wkending' => $request['weekending']
            ]);

            $save_success = $sale->save();

            if ($save_success) {
                $sales[] = $sale;
            }
        }

        return $result->setDataOnSuccess($sales);
    }
    
    private function deletePendingInvoiceItems($pending_deletes)
    {
        if (isset($pending_deletes['sales']) && count($pending_deletes['sales']) > 0) {
            Invoice::destroy($pending_deletes['sales']);
            $sales_ids = [];
            foreach ($pending_deletes['sales'] as $key => $value) {
                $sales_ids[] = $value['invoiceId'];
            }

            DB::table('invoices')->whereIn('invoice_id', $sales_ids)->delete();
        }

        if (isset($pending_deletes['overrides']) && count($pending_deletes['overrides']) > 0) {
            $override_ids = [];
            foreach ($pending_deletes['overrides'] as $key => $value) {
                $override_ids[] = $value['overrideId'];
            }

            DB::table('overrides')->whereIn('ovrid', $override_ids)->delete();
        }

        if (isset($pending_deletes['expenses']) && count($pending_deletes['expenses']) > 0) {
            $expense_ids = [];
            foreach ($pending_deletes['expenses'] as $key => $value) {
                $expense_ids[] = $value['expenseId'];
            }

            DB::table('expenses')->whereIn('expid', $expense_ids)->delete();
        }
    }```

您需要通过在 saveApiInvoice() 函数中 try{} 块的末尾添加 DB::commit(); 来提交您的数据库事务,然后再返回结果。

public function saveApiInvoice(Request $request): JsonResponse
    {
        $result = new OpResult();
        DB::beginTransaction();

        try {
            $this->deletePendingInvoiceItems($request['pendingDeletes']);
            $sales = $this->saveSaleRecords($request)->getData();
            $overrides = $this->saveOverrideRecords($request)->getData();
            $expenses = $this->saveExpenseRecords($request)->getData();

            $payroll = $this->savePayrollInfo($request, $sales, $overrides, $expenses)->getData();

            $this->paystubService->processPaystubJob($request['issueDate']);

            DB::commit(); // <--- Missing commit

            return $result->setData([
                'sales' => $sales,
                'overrides' => $overrides,
                'expenses' => $expenses,
                'payroll' => $payroll
            ])->getResponse();
            
        } catch (\Exception $ex) {
            DB::rollBack();

            return $result->setToFail($ex)
                ->getResponse();
        }
    }