如果子关系在 Laravel 中有结果,我如何只返回父级,如果关系是三重嵌套的?
Posted
技术标签:
【中文标题】如果子关系在 Laravel 中有结果,我如何只返回父级,如果关系是三重嵌套的?【英文标题】:How do I only return the parent if child has results in Laravel, if the relations are triple nested? 【发布时间】:2021-05-13 07:47:35 【问题描述】:我有以下关系Client
> belongsToMany Brand
> hasMany Handles
> hasMany 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');
目前,我在控制器中执行以下操作以获取句柄所需的内容。
/**
* 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 模型需要多少费用?它与品牌 > 处理 > 内容的设置相同?
【问题讨论】:
不应该更像$client->with(['brands'])->whereHas('handles', function ($query) $query->whereBetween....
@C4pt4inC4nn4bis 不,只是查询Client::handles();
也许这有帮助webdevetc.com/programming-tricks/laravel/laravel-eloquent/…
【参考方案1】:
我相信您的主查询中还需要嵌套 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() 部分过滤关联的记录,但您还需要在主查询中使用此过滤器来删除具有空集合的此类记录
【讨论】:
以上是关于如果子关系在 Laravel 中有结果,我如何只返回父级,如果关系是三重嵌套的?的主要内容,如果未能解决你的问题,请参考以下文章
如果子字符串包含在引用字符串中,如何使用布尔表达式进行匹配?
如果子查询没有返回结果,为啥“= ALL(子查询)”评估为真?