Laravel中如何合并BillPayment与InvoicePayment查询结果并统一获取?
问题描述
我在Laravel控制器里写了两个查询:
$bill_payment = BillPayment::whereIn('bill_id', $bill); $invoice_payments = InvoicePayment::whereIn('invoice_id', $invoice);
还有日期筛选的代码:
if(!empty($request->from_date) && !empty($request->until_date)) { $bill_payment->whereBetween('date', [$request->from_date, $request->until_date]); $invoice_payments->whereBetween('date', [$request->from_date, $request->until_date]); $data['from_date'] = $request->from_date; $data['until_date'] = $request->until_date; } $invoice_payment = $invoice_payments->get();
现在只能获取其中一个模型的结果,怎么一次性拿到bill_payment和invoice_payments的查询结果?
对应的Blade视图代码:
@forelse($invoice_payment as $payment) <tr> <td>{{ Verta::instance($payment->date)->format('j F Y') }} </td> <td>{{ \Auth::user()->invoiceNumberFormat($payment->invoice_id) }} </td> <td>{{ $payment->payment_type }} </td> <td> {{ \Auth::user()->priceFormat($payment->amount) }}</td> {{-- {{ dd($payment);}} --}} </tr> @empty <tr> <td colspan="6" class="text-center text-dark"> <p>{{ __('No Data Found') }}</p> </td> </tr> @endforelse
两个数据表迁移结构(仅bill_id和invoice_id不同):
Schema::create('bill_payments', function (Blueprint $table) { $table->bigIncrements('id'); $table->integer('bill_id'); $table->date('date'); $table->float('amount')->default('0.00'); $table->integer('account_id'); $table->integer('payment_method'); $table->string('reference'); $table->text('description'); $table->timestamps(); });
解决方案
1. 控制器合并查询结果
分别执行两个查询的get()方法,再把结果合并成一个集合:
// 执行两个查询获取各自结果 $billPayments = $bill_payment->get(); $invoicePayments = $invoice_payments->get(); // 合并两个集合 $allPayments = $billPayments->merge($invoicePayments); // 可选:按日期排序(正序/倒序按需选择) $allPayments = $allPayments->sortByDesc('date'); // 把合并后的集合传入视图 $data['payments'] = $allPayments;
2. 修改视图适配两种数据
因为两个模型分别有bill_id和invoice_id,视图里需要区分处理:
@forelse($payments as $payment) <tr> <td>{{ Verta::instance($payment->date)->format('j F Y') }} </td> <td> @if(isset($payment->invoice_id)) {{ \Auth::user()->invoiceNumberFormat($payment->invoice_id) }} @elseif(isset($payment->bill_id)) {{ \Auth::user()->billNumberFormat($payment->bill_id) }} {{-- 替换成你实际的账单编号格式化方法 --}} @endif </td> <td>{{ $payment->payment_type }} </td> <td> {{ \Auth::user()->priceFormat($payment->amount) }}</td> </tr> @empty <tr> <td colspan="6" class="text-center text-dark"> <p>{{ __('No Data Found') }}</p> </td> </tr> @endforelse
优化小技巧
如果不想在视图里写判断,可以在两个模型中添加访问器统一字段名:
- 在
BillPayment模型中:
public function getDocumentIdAttribute() { return $this->bill_id; }
- 在
InvoicePayment模型中:
public function getDocumentIdAttribute() { return $this->invoice_id; }
这样视图里可以直接用$payment->document_id,不用区分是账单还是发票,代码更简洁。
内容的提问来源于stack exchange,提问作者Mehdi Bakhtiari
相关产品推荐
相关产品推荐

