【问题标题】:Laravel filtering a hasMany relationLaravel 过滤 hasMany 关系
【发布时间】:2021-10-08 19:17:53
【问题描述】:

首先回答我的问题。一个用户有很多contacts 和一个contact 有很多anniversaries。我想过滤即将到来的周年纪念日。到目前为止,我有这个:

$filtered = auth()->user()->contacts()->get()->each(function ($contact) {
    $contact->anniversaries->filter(function ($anniversary) {

        // return true or false based on a method on the anniversary model
        return $anniversary->method() == true;

    });
});

但这只是返回所有联系人(显然)及其所有周年纪念日,我希望在调用$anniversary->method() 时排除那些错误的联系人。

$anniversary->method() 中的内容并不重要,这只会返回 truefalse

当我执行以下操作时,它会起作用:

$collection = auth()->user()->anniversaries()->get();

$filtered = $collection->filter(function ($anniversary) {
    return $anniversary->method() == true;
});

我只得到$anniversary->method() 确实是true 的周年纪念日。

我的问题主要是,为什么会发生这种情况,我只是想了解它,而不是如何让它工作的答案。提前感谢您提供任何见解!

【问题讨论】:

    标签: php laravel filter


    【解决方案1】:

    在第一个示例中,您只过滤每个联系人的anniversaries。您没有直接过滤contacts

    $filtered = auth()->user()->contacts()->get()->each(function ($contact) {
        // You are filtering only the anniversaries of each contact
        $anniversaries = $contact->anniversaries->filter(function ($anniversary) {
            return $anniversary->method() == true;
    
        });
    
        // over here you should get the same as in your second example
        dd($anniversaries);
    });
    

    在您的第二个示例中,您正在执行以下伪代码:

    1. 获取每个用户的所有纪念日
    2. 过滤匹配$anniversary->method() === true的周年纪念日

    要在第一个示例中获得相同的结果,您必须使用 filter->count() 的组合

    $filtered = auth()->user()->contacts()->get()->filter(function ($contact) {
        $filteredByMethod = $contact->anniversaries->filter(function ($anniversary) {
    
            // return true or false based on a method on the anniversary model
            return $anniversary->method() == true;
        });
    
        return $filteredByMethod->count() > 0;
    });
    

    哪个性能更高超出了此答案的范围。

    快速提示

    来自Laravel's collections 的方法filter 需要返回一个truthy 值作为过滤依据。由于您的method 返回true or false,因此您可以直接调用该方法而无需与true 进行比较:

    $collection = auth()->user()->anniversaries()->get();
    
    $filtered = $collection->filter(function ($anniversary) {
        return $anniversary->method();
    });
    

    【讨论】:

      猜你喜欢
      • 2019-04-04
      • 2019-03-04
      • 1970-01-01
      • 2014-09-30
      • 2021-12-14
      • 2020-03-25
      • 2021-03-22
      • 2021-09-24
      • 2016-03-17
      相关资源
      最近更新 更多