【问题标题】:Laravel: Why does eager loading only keep results for last model?Laravel:为什么急切加载只保留最后一个模型的结果?
【发布时间】:2019-03-03 17:24:16
【问题描述】:

如果我执行以下操作:

App\Assignment::with(['unit.records' => function ($q) {
                    $q->where('process_date', '>=', '2016-01-01')
                        ->where('process_date', '<=', '2018-09-27')
                        ->orderBy('process_date')
                        ->orderBy('process_hour')
                        ->limit(1);
                    }])
                    ->whereIn('id', [9])
                    ->get();

然后我得到以下结果:

Illuminate\Database\Eloquent\Collection {#1104
 all: [
   App\Assignment {#1112
     id: 9,
     unit_id: 6,
     start_date: "2015-11-25",
     end_date: "2016-01-04",
     unit: App\Unit {#986
       id: 6,
       records: Illuminate\Database\Eloquent\Collection {#945
         all: [
           App\Record {#853
             id: 6624,
             unit_id: 6,
             process_date: "2017-09-19",
             process_hour: 14,
           },
         ],
       },
     },
   },
 ],
}

注意加载的单元如何具有匹配查询的记录。

现在,如果我使用完全相同的查询,但将另一个赋值 (49) 添加到我的 whereIn 数组:

App\Assignment::with(['unit.records' => function ($q) {
                    $q->where('process_date', '>=', '2016-01-01')
                        ->where('process_date', '<=', '2018-09-27')
                        ->orderBy('process_date')
                        ->orderBy('process_hour')
                        ->limit(1);
                    }])
                    ->whereIn('id', [9,49])
                    ->get();

作业 49 的记录已显示,但作业 9 的记录不再显示:

Illuminate\Database\Eloquent\Collection {#1032
 all: [
   App\Assignment {#1014
     id: 9,
     unit_id: 6,
     start_date: "2015-11-25",
     end_date: "2016-01-04",
     unit: App\Unit {#1283
       id: 6,
       records: Illuminate\Database\Eloquent\Collection {#1254
         all: [],
       },
     },
   },
   App\Assignment {#1061
     id: 49,
     unit_id: 29,
     start_date: "2017-02-24",
     end_date: "9999-12-31",
     unit: App\Unit {#1279
       id: 29,
       records: Illuminate\Database\Eloquent\Collection {#1131
         all: [
           App\Record {#1284
             id: 6062,
             unit_id: 29,
             process_date: "2017-03-10",
             process_hour: 13,
           },
         ],
       },
     },
   },
 ],
}

与分配 9 的条件匹配的记录显然存在,但由于某种原因,当查询发现多个分配具有与条件匹配的单元/记录时,它不会被加载。

我也用更多的分配测试了这个,在每种情况下,记录只会显示数组中的最后一个分配。

这是怎么回事?

【问题讨论】:

    标签: laravel laravel-5 eloquent laravel-5.1 eager-loading


    【解决方案1】:

    在 Laravel 中没有对预先加载的原生支持。

    我为它创建了一个包:https://github.com/staudenmeir/eloquent-eager-limit

    在父模型和相关模型中使用 HasEagerLimit 特征。

    class Unit extends Model {
        use \Staudenmeir\EloquentEagerLimit\HasEagerLimit;
    }
    
    class Record extends Model {
        use \Staudenmeir\EloquentEagerLimit\HasEagerLimit;
    }
    

    然后您可以将-&gt;limit(1) 应用到您的关系中,您会得到预期的结果。

    【讨论】:

      【解决方案2】:

      问题是你使用:

      ->limit(1)
      

      这将关系记录的数量限制为 1。只需删除此行就可以了。

      【讨论】:

      • 我需要限制结果,因为有大量记录适合我的查询,我无法将它们全部存储在内存中,无论如何我只需要第一个。有没有办法限制每个关系而不是所有关系的结果?
      • @samalamma708 没有简单的方法。您预计App\Assignment 有多少条记录?例如,您展示了-&gt;whereIn('id', [9,49])。这个数组有多大?也可以看看github.com/laravel/framework/issues/18014
      • 将有 100 个作业,每个作业可能有 1000 条记录
      • @samalamma708 所以你需要先找到查询来得到那些结果(单位记录),然后你可以尝试为Assignment设置关系。据我所知,除非您不使用 github 链接中提供的解决方案,否则您无法使用关系来做到这一点
      猜你喜欢
      • 2013-05-28
      • 1970-01-01
      • 2019-05-19
      • 2015-06-19
      • 2013-06-10
      • 2013-05-16
      • 2020-09-08
      • 2013-03-27
      相关资源
      最近更新 更多