英文:
Laravel: Has many through not respecting whereHas
问题
I am trying to construct a hasManyThrough
relationship in Laravel 10.
我正在尝试在 Laravel 10 中构建一个 hasManyThrough
关系。
I have 3 tables: users
table (standard Laravel columns), client_assignments
, and media_ad_plans
.
我有3个表格:users
表格(标准 Laravel 列),client_assignments
和 media_ad_plans
。
A user can be assigned to multiple clients in the client_assignments
table. In the media_ad_plans
table an entry belongs to one client.
用户可以在 client_assignments
表格中分配给多个客户。在 media_ad_plans
表格中,一项属于一个客户。
In my Users
model I am defining the relationship like so:
在我的 Users
模型中,我像这样定义了关系:
public function adPlans(): HasManyThrough
{
return $this->hasManyThrough(
AdPlan::class,
ClientAssignment::class,
'user_id',
'client_id',
'id',
'client_id'
);
}
在我的 Users
模型中,我像这样定义了关系:
However, when doing something like:
但是,当进行如下操作时:
$users = User::with('adPlans.client')->whereHas('adPlans', function ($query) {
return $query->duringTodayUsing('material_deadline', false); // a custom scope
})->get();
$users = User::with('adPlans.client')->whereHas('adPlans', function ($query) {
return $query->duringTodayUsing('material_deadline', false); // a custom scope
})->get();
All of the ad plan items associated with a user are returned, not just the one's that match the whereHas
statement. I've tried a simple query within the whereHas
closure but it does not change the output - I still get all items for the user. I suspect my relationship is malformed or perhaps I am doing something "illegal." I am not getting any errors.
返回了与用户关联的所有广告计划项,而不仅仅是与 whereHas
语句匹配的那些。我尝试在 whereHas
闭包中使用简单的查询,但它并没有改变输出 - 我仍然得到了用户的所有项目。我怀疑我的关系可能是错误的,或者我可能做了一些“不合法”的事情。我没有收到任何错误。
Client Assignments:
客户分配:
Ad Plan (useful fields per the question):
广告计划(根据问题的有用字段):
英文:
I am trying to construct a hasManyThrough
relationship in Laravel 10.
I have 3 tables: users
table (standard Laravel columns), client_assignments
, and media_ad_plans
A user can be assigned to multiple clients in the client_assignments
table. In the media_ad_plans
table an entry belongs to one client.
In my Users
model I am defining the relationship like so:
public function adPlans(): HasManyThrough
{
return $this->hasManyThrough(
AdPlan::class,
ClientAssignment::class,
'user_id',
'client_id',
'id',
'client_id'
);
}
However, when doing something like:
$users = User::with('adPlans.client')->whereHas('adPlans', function ($query) {
return $query->duringTodayUsing('material_deadline', false); // a custom scope
})->get();
All of the ad plan items associated with a user are returned, not just the one's that match the whereHas
statement. I've tried a simple query within the whereHas
closure but it does not change the output - I still get all items for the user. I suspect my relationship is malformed or perhaps I am doing something "illegal." I am not getting any errors.
Client Assignments:
Ad Plan (useful fields per the question):
答案1
得分: 3
->whereHas()
在独立的->with()
子句上没有效果。您的代码按预期工作;whereHas()
根据'adPlans', function ($query) { ... })
来过滤返回的User
记录,但->with('adPlans.client')
正确地返回每个User
关联的所有adPlans
记录。
您可以将逻辑复制到->with()
子句上,如下所示:
$users = User::with(['adPlans' => function ($query) {
return $query->with('client')->duringTodayUsing('material_deadline', false);
}])->whereHas('adPlans', function ($query) {
return $query->duringTodayUsing('material_deadline', false);
})->get();
或者使用Laravel的->withWhereHas()
子句:
$users = User::withWhereHas('adPlans', function ($query) {
return $query->with('client')->duringTodayUsing('material_deadline', false);
})->get();
文档链接:
英文:
->whereHas()
has no effect on a separate ->with()
clause. Your code is working exactly as expected; whereHas()
is filtering which User
records are returned, based on 'adPlans', function ($query) { ... })
, but ->with('adPlans.client')
is correctly returning ALL of each User
's associated adPlans
Records.
You either need to duplicate your logic onto your ->with()
clause, like:
$users = User::with(['adPlans' => function ($query) {
return $query->with('client')->duringTodayUsing('material_deadline', false);
}])->whereHas('adPlans', function ($query) {
return $query->duringTodayUsing('material_deadline', false);
})->get();
Or use Laravel's ->withWhereHas()
Clause:
$users = User::withWhereHas('adPlans', function ($query) {
return $query->with('client')->duringTodayUsing('material_deadline', false);
})->get();
Documentation:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论