简体   繁体   English

如何过滤 Laravel 中的嵌套集合?

[英]How to filter nested collection in Laravel?

I've been scouring Stack for the last couple of hours, and while several seem related, nothing appears to be working correctly.在过去的几个小时里,我一直在搜索 Stack,虽然有几个似乎相关,但似乎没有任何工作正常。

I have a GraphQL API running on Laravel, and am trying to filter out the current_user from a mutator so that I don't have to do it on the frontend.我有一个在 Laravel 上运行的 GraphQL API,我正在尝试从 mutator 中过滤掉 current_user,这样我就不必在前端执行此操作。

A User hasMany Trips, and each Trip belongsToMany Users via a pivot table called trip_user .一个用户有许多行程,每个行程通过一个名为trip_user的数据透视表trip_user多个用户。 On the Trip model, I am eager loading things such as Todos and Users like this:在 Trip 模型上,我很想加载诸如 Todos 和 Users 之类的东西:

Trip.php旅行.php

class Trip extends Model
{
    protected $with = [
        'todos', 'shopping_list_items', 'users'
    ];

    public function users(): BelongsToMany
    {
        return $this->belongsToMany(User::class);
    }

    // other relationships
}

Then in my TripQuery which returns my results to my GraphQL client, I am trying to return all of a user's trips, but filter out current_user, like so:然后在将结果返回给我的 GraphQL 客户端的 TripQuery 中,我试图返回用户的所有行程,但过滤掉 current_user,如下所示:

class TripsQuery
{
    public function find_by_user($rootValue, array $args, GraphQLContext $context, ResolveInfo $resolveInfo)
    {
        $user = $context->user();

        if ($user) {
            // all trip friends and todos automatically eager loaded on the model
            $trips = $user->trips()->get();

            return $trips->each->users->filter(function ($friend) use ($user) {
                return $friend->id !== $user->id;
            });
        }

        return null;
    }
}

When I run this however, the only user it's returning is current_user, and for some reason it's returning an empty array of Todos , even though it should return 4 of them.然而,当我运行它时,它返回的唯一用户是 current_user,并且由于某种原因它返回一个空数组Todos ,即使它应该返回其中的 4 个。 I'm not sure why the ->filter() function isn't working (I am brand new to Laravel, so there's that).我不确定为什么->filter()函数不起作用(我是 Laravel 的新手,所以就是这样)。

Why isn't the ->filter working correctly?为什么->filter不能正常工作?

EDIT Including the results from a dd() :编辑包括来自dd()的结果:

array:2 [
  0 => array:9 [
    "id" => 1
    "name" => "Trip 1"
    "description" => "Planning for Trip 1"
    "owner_id" => 1
    "created_at" => "2020-11-18T06:28:45.000000Z"
    "updated_at" => "2020-11-18T06:28:45.000000Z"
    "todos" => array:4 [
      0 => array:6 [
        "id" => 1
        "title" => "Book car rental"
        "checked" => 0
        "trip_id" => 1
        "created_at" => "2020-11-18T17:00:46.000000Z"
        "updated_at" => "2020-11-18T17:00:46.000000Z"
      ]
      1 => array:6 [
        "id" => 2
        "title" => "Check in to flights"
        "checked" => 0
        "trip_id" => 1
        "created_at" => "2020-11-18T17:00:46.000000Z"
        "updated_at" => "2020-11-18T17:00:46.000000Z"
      ]
      2 => array:6 [
        "id" => 3
        "title" => "Drop off dog at sitter"
        "checked" => 1
        "trip_id" => 1
        "created_at" => "2020-11-18T17:00:46.000000Z"
        "updated_at" => "2020-11-18T17:00:46.000000Z"
      ]
      3 => array:6 [
        "id" => 4
        "title" => "Stop at store"
        "checked" => 1
        "trip_id" => 1
        "created_at" => "2020-11-18T17:00:46.000000Z"
        "updated_at" => "2020-11-18T17:00:46.000000Z"
      ]
    ]
    "users" => array:3 [
      0 => array:19 [
        "id" => 1
        "api_token" => null
        "email" => "test@gmail.com"
        "email_verified_at" => "2020-11-07T15:38:48.000000Z"
        "avatar_url" => null
        "created_at" => "2020-11-07T15:38:48.000000Z"
        "updated_at" => "2020-11-16T20:55:02.000000Z"
        "pivot" => array:2 [
          "trip_id" => 1
          "user_id" => 1
        ]
      ]
      1 => array:19 [
        "id" => 2
        "api_token" => null
        "email" => "michael.scott@gmail.com"
        "email_verified_at" => "2020-11-07T15:38:48.000000Z"
        "avatar_url" => null
        "created_at" => "2020-11-07T15:38:48.000000Z"
        "updated_at" => "2020-11-07T15:38:48.000000Z"
        "pivot" => array:2 [
          "trip_id" => 1
          "user_id" => 2
        ]
      ]
      2 => array:19 [
        "id" => 3
        "api_token" => null
        "email" => "pam.beasley@gmail.com"
        "email_verified_at" => "2020-11-07T15:38:48.000000Z"
        "avatar_url" => null
        "created_at" => "2020-11-07T15:38:48.000000Z"
        "updated_at" => "2020-11-07T15:38:48.000000Z"
        "pivot" => array:2 [
          "trip_id" => 1
          "user_id" => 3
        ]
      ]
    ]
  ]
  1 => array:9 [
    "id" => 2
    "name" => "Trip 2"
    "description" => "Trip 2 Description"
    "owner_id" => 1
    "created_at" => "2020-11-18T06:28:45.000000Z"
    "updated_at" => "2020-11-18T06:28:45.000000Z"
    "todos" => []
    "shopping_list_items" => []
    "users" => array:1 [
      0 => array:19 [
        "id" => 1
        "api_token" => null
        "email" => "benny.timkins@gmail.com"
        "email_verified_at" => "2020-11-07T15:38:48.000000Z"
        "avatar_url" => null
        "created_at" => "2020-11-07T15:38:48.000000Z"
        "updated_at" => "2020-11-16T20:55:02.000000Z"
        "pivot" => array:2 [
          "trip_id" => 2
          "user_id" => 1
        ]
      ]
    ]
  ]
]

Each does only return current collection for chaining oportunity, does not mutate the collection .每个只返回当前集合以用于链接机会, 不会改变集合

I think the correct solution from how it looks like you use GraphQL , is to filter the eager loading using the with() method and adding a query to it.我认为从您使用GraphQL ,正确的解决方案是使用with()方法过滤急切加载并向其添加查询。

return $user->trips()->with(['users' => function ($query) use ($user) {
    $query->where('id', '!=', $user->id);
}])->get();

For better code style, never check for a condition, invert it and return early.为了更好的代码风格,永远不要检查条件,将其反转并尽早返回。

$user = $context->user();

if (! $user) {
    return null;
}

return $user->trips()->with(['users' => function ($query) use ($user) {
    $query->where('users.id', '!=', $user->id);
}])->get();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM