withTrashed 在 hasManyThrough 关系的中间模型上
withTrashed on the intermediate model of a hasManyThrough relation
我有 3 个 class 是这样的:
Exhibitor
'- Bills
'- Tickets
Bills 和 Tickets 都使用 SoftDeletes 特性,并且在 Exhibitor 上 class 我有这样的关系:
public function tickets()
{
return $this->hasManyThrough(Ticket::class, Bill::class);
}
我需要获取所有票证,包括已删除的票证 (withTrashed
),但这还需要包括所有已删除的票据。问题是,withTrashed 仅适用于 Tickets 模型,而不适用于 Bills。
这个查询
$tickets = exhibitor()->tickets()->withTrashed()
->where('bills.updated_at', '>=', Carbon::parse($since))
->orderBy('tickets.id')
->get();
生成此 SQL
select `tickets`.*, `bills`.`exhibitor_id` from `tickets`
inner join `bills` on `bills`.`id` = `tickets`.`bill_id`
where `bills`.`deleted_at` is null
and `bills`.`exhibitor_id` = ?
and `bills`.`updated_at` >= ?
order by `tickets`.`id` asc
而我需要这个 SQL 而不是像这样的“bills
。deleted_at
是空的”:
select `tickets`.*, `bills`.`exhibitor_id` from `tickets`
inner join `bills` on `bills`.`id` = `tickets`.`bill_id`
where `bills`.`exhibitor_id` = ?
and `bills`.`updated_at` >= ?
order by `tickets`.`id` asc
但是我没有看到任何可以为 Bill 模型设置 withTrashed() 的选项。我认为应该可以在 hasManyThrough 方法上设置回调查询,但根据 API 不支持此操作。这看起来很简单,我觉得我忽略了一些东西,但我找不到它...
我会在票据模型上定义一个范围,因为查询变得有点复杂。
public function scopeBillsSince($query, $since)
return $query->whereHas('bills', function ($query2) use ($since) {
return $query2->withThrashed()->where('updated_at', '>=', Carbon::parse($since))
});
}
现在使用该范围,您可以像这样查询票证:
$tickets = exhibitor()->tickets()->withTrashed()->billsSince($since);
目前无法做到:https://github.com/laravel/framework/issues/23039
如果您不介意安装外部包,您可以使用我创建的这个包:
https://github.com/staudenmeir/eloquent-has-many-deep
class Exhibitor extends Model
{
use \Staudenmeir\EloquentHasManyDeep\HasRelationships;
public function tickets()
{
return $this->hasManyDeep(Ticket::class, [Bill::class])
->withTrashed('bills.deleted_at');
}
}
我有 3 个 class 是这样的:
Exhibitor
'- Bills
'- Tickets
Bills 和 Tickets 都使用 SoftDeletes 特性,并且在 Exhibitor 上 class 我有这样的关系:
public function tickets()
{
return $this->hasManyThrough(Ticket::class, Bill::class);
}
我需要获取所有票证,包括已删除的票证 (withTrashed
),但这还需要包括所有已删除的票据。问题是,withTrashed 仅适用于 Tickets 模型,而不适用于 Bills。
这个查询
$tickets = exhibitor()->tickets()->withTrashed()
->where('bills.updated_at', '>=', Carbon::parse($since))
->orderBy('tickets.id')
->get();
生成此 SQL
select `tickets`.*, `bills`.`exhibitor_id` from `tickets`
inner join `bills` on `bills`.`id` = `tickets`.`bill_id`
where `bills`.`deleted_at` is null
and `bills`.`exhibitor_id` = ?
and `bills`.`updated_at` >= ?
order by `tickets`.`id` asc
而我需要这个 SQL 而不是像这样的“bills
。deleted_at
是空的”:
select `tickets`.*, `bills`.`exhibitor_id` from `tickets`
inner join `bills` on `bills`.`id` = `tickets`.`bill_id`
where `bills`.`exhibitor_id` = ?
and `bills`.`updated_at` >= ?
order by `tickets`.`id` asc
但是我没有看到任何可以为 Bill 模型设置 withTrashed() 的选项。我认为应该可以在 hasManyThrough 方法上设置回调查询,但根据 API 不支持此操作。这看起来很简单,我觉得我忽略了一些东西,但我找不到它...
我会在票据模型上定义一个范围,因为查询变得有点复杂。
public function scopeBillsSince($query, $since)
return $query->whereHas('bills', function ($query2) use ($since) {
return $query2->withThrashed()->where('updated_at', '>=', Carbon::parse($since))
});
}
现在使用该范围,您可以像这样查询票证:
$tickets = exhibitor()->tickets()->withTrashed()->billsSince($since);
目前无法做到:https://github.com/laravel/framework/issues/23039
如果您不介意安装外部包,您可以使用我创建的这个包: https://github.com/staudenmeir/eloquent-has-many-deep
class Exhibitor extends Model
{
use \Staudenmeir\EloquentHasManyDeep\HasRelationships;
public function tickets()
{
return $this->hasManyDeep(Ticket::class, [Bill::class])
->withTrashed('bills.deleted_at');
}
}