You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel条件式预加载:如何按model_type控制关联加载?

解决方案

你可以通过延迟加载关联的方式,先获取所有符合条件的分页记录,再针对model_type为campaign_channel_rule的子集加载关联关系,这样campaign类型的记录就不会触发关联查询。

代码实现

$paginated = File::whereIn('model_id', $channelRules->pluck('id'))
    ->where('model_type', 'campaign_channel_rule')
    ->orWhere(function($query) use($campaign) {
        $query->where('model_type', 'campaign')->where('model_id', $campaign->id);
    })
    ->paginate(15);

// 仅对model_type为campaign_channel_rule的文件加载关联
$paginated->getCollection()
    ->where('model_type', 'campaign_channel_rule')
    ->load('campaignChannelRule.channel.channel');

原理说明

  1. 先执行主查询获取所有符合条件的分页记录,此时不会预加载任何关联。
  2. 从分页结果的集合中筛选出model_type为campaign_channel_rule的记录,调用load()方法延迟加载指定关联。
  3. campaign类型的记录不会执行关联查询,完全符合你的需求。

备选方案:分查询合并分页

如果需要严格分开两次查询(比如关联查询条件复杂),可以分别查询两种类型的记录,合并后手动创建分页器:

// 查询带关联的campaign_channel_rule类型文件
$channelRuleFiles = File::whereIn('model_id', $channelRules->pluck('id'))
    ->where('model_type', 'campaign_channel_rule')
    ->with('campaignChannelRule.channel.channel')
    ->get();

// 查询不带关联的campaign类型文件
$campaignFiles = File::where('model_type', 'campaign')
    ->where('model_id', $campaign->id)
    ->get();

// 合并集合
$allFiles = $channelRuleFiles->merge($campaignFiles);

// 手动创建分页器
$perPage = 15;
$currentPage = request()->get('page', 1);
$paginatedFiles = new \Illuminate\Pagination\LengthAwarePaginator(
    $allFiles->forPage($currentPage, $perPage),
    $allFiles->count(),
    $perPage,
    $currentPage,
    ['path' => request()->url(), 'query' => request()->query()]
);

内容的提问来源于stack exchange,提问作者Jenssen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 01:24:31