我有两个模型,User
和Training
。它们与is_speaker
和is_creator
等其他数据透视字段具有多对多关系。我想:
SELECT * FROM users WHERE business_unit = Finance
; training
的相关is_speaker = true
; 换句话说,访问者搜索其(第一)发言人属于指定业务单位的所有培训。
这是我到目前为止所尝试的:
$bu_users = $this->user->where( 'business_unit', $business_unit )->get();
$speakerTrainings = $bu_users->trainings()->wherePivot( 'is_speaker', true )->get();
dd( $speakerTrainings );
// Returns: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'pivot' in 'where clause' (SQL: select * from `trainings` where (select count(*) from `users` inner join `training_user` on `users`.`id` = `training_user`.`user_id` where `training_user`.`training_id` = `trainings`.`id` and `business_unit` = Finance and `users`.`is_active` = 1) >= 1 and `pivot` = is_speaker)
$bu_trainings = $this->training->with( 'users' )
->where( 'business_unit', '=', $business_unit )
->wherePivot( 'is_speaker', true)
->get();
dd( $bu_trainings );
// Returns: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'business_unit' in 'where clause' (SQL: select * from `trainings` where `business_unit` = Finance and `pivot` = is_speaker)
答案 0 :(得分:1)
你关闭了。现在我们需要混合您的两个查询并添加一些whereHas
试试这个(此代码返回属于指定业务单位的所有用户,并且也是任何培训的发言人):
$users = $this->user
->whereHas('trainings', function($q){
$q->where('training_user.is_speaker', true);
})
->where('business_unit', $business_unit)
->get();
此代码将返回所有至少有一位来自指定业务单位的发言人的培训:
$trainings = $this->training->whereHas( 'users', function( $q )
{
$business_unit = Input::get( 'bu' );
$q->where( 'training_user.is_speaker', true );
$q->where( 'business_unit', $business_unit );
})->get;
我知道这不是理想的,但这是我能想到的唯一有效的方法
首先,为了便于使用,请定义speakers
关系
public function speakers(){
return $this->belongsToMany('User')->wherePivot('is_speaker', true);
}
然后,首先,急切加载所有发言者,然后过滤(编辑)训练:
$business_unit = Input::get('bu');
$trainings = $this->training->has('speakers')->with('speakers')->get();
$trainings = $trainings->filter(function($training) use ($business_unit){
return $training->speakers->sortBy('training_user.id')->first()->business_unit == $business_unit;
});