【问题标题】:How to retrieve a model with a filter on one of it's hasMany relationships?如何在其中一个 hasMany 关系上使用过滤器检索模型?
【发布时间】:2021-10-19 14:44:35
【问题描述】:

我正在尝试获取模型并将过滤器添加到其中一个 hasMany 关系中。

假设我有两个模型。一个是Location,另一个是LocationAnalytic

Location 模型有很多 LocationAnalytic 类。因此,当我想通过 Id 检索位置时,它会返回所有 Location 数据并返回 LocationAnalytic 数据作为数组。在我的例子中,一个 Location 模型可以与数千个 LocationAnalytic 模型相关。

我需要获取Location 模型,但也只获取已通过给定过滤器过滤的相关LocationAnalytic 数据。通过这种方式,我将获得相同的 Location 数据,并且在同一响应中也仅获得几个 LocationAnalytic 数据。

类似于 whereHas 指令,但它不会检查是否存在,它只会过滤模型的关系。

我的查询将如下所示;

query($id:Int!) {
    location (id: $id) {
        id
        parent_id
        name
        admin_level
        country
        analytic {
            id
            category_id
            total_listings_count
            new_listings_count
            expired_listings_count
            created_at
        }
    }
}

我的过滤器将类似于以下内容

{
  "location_idid": 100075,
  "analytics": {
      "AND": [
          { "column": "CATEGORY_ID", "operator": "EQ", "value": 390005 }
      ]
  }
}

【问题讨论】:

  • 下面的答案对你有用吗?如果是这样,请将其标记为关闭您的问题的答案

标签: laravel laravel-lighthouse


【解决方案1】:

使用with()方法的第二个参数过滤关系

$locationId;

$filter = ['field' => 'category_id', 'operator' => '=', 'value' => 390005];

$location = Location::with('locationAnalytics', function($locationAnQuery) use ($filter) {
    $locationAnQuery->where($filter['field'], $filter['operator'], $filter['value']);
})->find($locationId);

【讨论】:

  • 感谢您的想法,它提供了一个很好的起点,但我正在寻找 graphql 和 lighthouse 包中的答案。
【解决方案2】:

目前我找到的最佳解决方案是;

通过使用@method 指令,我能够创建一个获取所有过滤器并返回结果的方法。

https://lighthouse-php.com/master/api-reference/directives.html#method

我在 Location 类型中添加了一个名为 filteredAnalytic 的新字段

type Location {
    id: Int
    filteredAnalytic(category_id: Int, tenure_id: Int, type_group_id: Int, contact_type_id: Int, source_id: Int, age_group_id: Int, room_count: Int): LocationAnalytic @method
}

我已将filteredAnalytic 名称的新方法添加到Location 模型

public function filteredAnalytic($category_id, $tenure_id, $type_group_id, $contact_type_id, $source_id, $age_group_id, $room_count)
    {
        return $this->hasMany(LocationAnalytic::class)
            ->where('category_id',$category_id)
            ->where('tenure_id', $tenure_id)
            ->where('type_group_id', $type_group_id)
            ->where('contact_type_id', $contact_type_id)
            ->where('source_id', $source_id)
            ->where('age_group_id', $age_group_id)
            ->where('room_count', $room_count)
            ->first();
    }

这样,我可以创建如下查询,并能够将过滤器传递给模型关系。

query($coordinates:CoordinatesInput, $category_id:Int, $tenure_id:Int, $type_group_id:Int, $contact_type_id:Int, $source_id:Int, $age_group_id:Int, $room_count:Int) {
    locations (coordinates: $coordinates) {
        id
        parent_id
        name
        admin_level
        country
        filteredAnalytic (category_id: $category_id, tenure_id: $tenure_id, type_group_id: $type_group_id, contact_type_id:$contact_type_id, source_id:$source_id, age_group_id:$age_group_id, room_count:$room_count) {
            id
            location_id
            created_at
        }
    }
}

带有过滤器,

{
   "coordinates" : {
      "lat": 41.671,
      "lng": 27.9714
  },
  "category_id": 30003,
  "tenure_id": 10001,
  "type_group_id": 310001,
  "contact_type_id": 110002,
  "source_id": 40002,
  "age_group_id": 300001,
  "room_count": null
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-20
    • 2011-03-17
    • 1970-01-01
    • 1970-01-01
    • 2015-04-16
    相关资源
    最近更新 更多