postgresql 如果子节点在Laravel中有结果,如果关系是三重嵌套的,我如何只返回父节点?

0lvr5msh  于 2023-01-12  发布在  PostgreSQL
关注(0)|答案(1)|浏览(112)

我有以下关系Client〉属于多个Brand〉有多个Handles〉有多个Content
如果Content有行,我将如何只返回Handles,如果Handles有行,我将如何只返回Brands,如果Client也有行,我将如何从PostgreSQL数据库中获取?
这是这些模型的翻版

客户端模型

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\SoftDeletes;

class Client extends Model
{
    use HasFactory;
    use SoftDeletes;

    protected $hidden = ['pivot'];

    protected $fillable = ['title', 'subscription_expire', 'subscription_level'];

    /**
     * Get brands for client
     *
     * @return BelongsToMany
     */
    public function brands(): BelongsToMany
    {
        return $this->belongsToMany(
            Brand::class,
            'organized_objects',
            'client_id',
            'object_id'
        )->wherePivot('object_type', 'brand');
    }
}

品牌型号

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;

class Brand extends Model
{
    use HasFactory;
    use SoftDeletes;

    /**
     * Get handles for brand
     *
     * @return BelongsToMany
     */
    public function handles(): BelongsToMany
    {
        return $this->belongsToMany(Handle::class, 'handle_pivots', 'handle_pivot_id', 'handle_id');
    }
}

手柄型号

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Factories\HasFactory;

class Handle extends Model
{
    use HasFactory;

    protected $fillable = ['name', 'platform'];

    /**
     * Get content of handle.
     *
     * @return HasMany
     */
    public function content(): HasMany
    {
        return $this->hasMany(PureContent::class, 'handle_id');
    }
}

目前,我正在我的控制器中执行以下操作,以获取句柄所需的内容。

<?php
/**
 * Client metrics
 *
 * Displays metrics for the given client
 *
 * @param Request $request
 * @param Client  $client
 *
 * @return JsonResponse
 */
public function index(Request $request, Client $client): JsonResponse
{
    $to = $request->get('to');
    $from = $request->get('from');
    $to_date = $to ? Carbon::parse($to) : Carbon::now();
    $from_date = $from ? Carbon::parse($from) : $to_date->copy()->startOfYear();

    $client_content = $client->with([
        'brands' => function ($q) use ($to_date, $from_date) {
            $q->with([
                'handles' => function ($q) use ($to_date, $from_date) {
                    $q->whereHas('content', function ($q) use ($to_date, $from_date) {
                        $q->whereBetween('created_at', [$from_date, $to_date]);
                    })->with(['content' => function ($q) use ($to_date, $from_date) {
                        $q->whereBetween('created_at', [$from_date, $to_date]);
                    }])->get();
                },
            ])->get();
        },
    ])->get();

    return response()->json($client_content);
}

但是当我在返回集合时,我仍然得到相关的集合只是空的。
例如,在查询中添加一个Collection模型需要多少钱?它的设置与brands〉handles〉content相同。

bsxbgnwa

bsxbgnwa1#

我相信您还需要在主查询中嵌套whereHas子句,以便过滤不相关的客户记录

$client_content=$client->with(.....)
                       ->whereHas('brands', function (Builder $query) use ($to_date, $from_date) {
                            $query->whereHas('handles', function (Builder $query) use ($to_date, $from_date) {
                                $query->whereHas('content', function (Builder $query) use ($to_date, $from_date) {
                                    $query->whereBetween('created_at', [$from_date, $to_date]);
                                });
                            });
                        })->get();

现在,您只是从with()部分过滤关联的记录,但是您还需要在主查询中使用此过滤器来删除具有空集合的记录

相关问题