php Laravel lazy eager loading with pagination

bsxbgnwa  于 2023-05-27  发布在  PHP
关注(0)|答案(2)|浏览(129)

我使用Laravel的Eloquent的lazy eager loading特性,首先查询一些payments,然后使用->load()payers eager loading到每个payment中。

说明:users hasMany payers hasAndBelongsToMany payments

下面是我使用的代码(花了一段时间才弄清楚,但它的工作)

//Get all the payments for the logged in user
    $payments = Payment::whereHas('payers', function($q){
        $q->where('user_id', '=', Auth::user()->id); 
    },'>=', DB::raw('1'))
    ->get();

    //lazy eager load the pivot data, which contains payer info for each payment
    $payments = $payments->load(array(
        'payers' => function($q){
            $q->where('user_id', '=', Auth::user()->id);
        }));

目前,查询仅使用get()来获取付款。如果我将其更改为paginate(),它也可以工作,但延迟加载失败,因为没有->load()分页方法。这意味着我必须始终查询所有付款。
如何对该查询进行分页?

**编辑:**表模式

zzwlnbp8

zzwlnbp81#

首先,从我最初的回答来看,我仍然相信你可以改进你最初的查询。如果你有一个用户,你想找到所有的付款,你应该能够通过一个简单的Eloquent关系,而不是直接通过Payment模型与一个更复杂的whereHas()语句。
其次,用于延迟急切加载的load()方法实际上附加到Illuminate\Database\Eloquent\Collection类。这就是所缺少的,并阻止您的懒惰加载工作。
如果你不得不延迟急切加载(急切加载在初始查询上都能正常工作,不管有没有分页),你会想把Paginator的项目 Package 在那个集合中。

$paginator = Auth::user()->payments()->paginate(10);

$payments = new Illuminate\Database\Eloquent\Collection($payments->getItems());
$payments->load('payer');
  • (注:未经测试!)*

实际上,您是在将分页器中的项目复制到它自己的新集合中。假设您需要生成的页面链接和加载的集合,您需要将这两个变量传递给视图。
Paginator确实有一个setItems()方法,可以覆盖原始的items数组,但我不知道它将如何影响其余的Paginator方法。谨慎使用。

  • 错误答案:*

看来你只为一个用户加载付款。当只有一个人时,你为什么需要急切地加载每个付款人,你**已经通过Auth::user()**了?
理想情况下,您的User模型上应该有一个payments()关系,您可以通过Auth::user()->payments加载该用户的付款。

m4pnthwp

m4pnthwp2#

$paginator = Auth::user()->payments()->paginate(10);

$payments = new Illuminate\Database\Eloquent\Collection($payments->getCollection());
$payments->load('payer');

相关问题