Laravel - 如何将 whereHas 与条件关系一起使用?
Laravel - how to use whereHas with conditional relationships?
我已经尝试解决这个问题 3 天了,但没有找到任何解决方案。
我在用户 table 和他们的个人资料 admin_profile、teacher_profile、student_profile 和 company_pofile 之间建立了有条件的一对一关系
用户模型中的关系如下所示:
function profile() {
switch ($this -> type) {
case 'other':
return $this -> hasOne('App\AdminProfile');
break;
case 'company':
return $this -> hasOne('App\CompanyProfile');
break;
case 'teacher':
return $this -> hasOne('App\TeacherProfile');
break;
case 'student':
return $this -> hasOne('App\StudentProfile');
break;
}
}
并且由于它是有条件的,所以在我调用 "get" 方法或其兄弟姐妹之一之前,预加载将不起作用。所以我使用 "load" 来获取这样的用户配置文件:
function getUser($id) {
$user = User::find($id) -> load('profile');
return response() -> json($user);
}
现在的问题是我想根据个人资料中的数据搜索用户,所以我这样做了:
if($request -> has('filter')) {
$users -> whereHas('profile', function ($q) use($request) {
$filter = explode($request -> filter, ',');
$q -> where ($filter[0], @$filter[1]);
});
}
当然因为条件关系,预加载是行不通的,这里是错误信息:
FatalErrorException in Builder.php line 580: Call to a member function
getRelationCountQuery() on null
我自己也走过这条路,很痛苦。我强烈建议您改用 Laravel 的多态关系。如果不能,处理此问题的最佳方法是对每种关系类型进行单独查询。但是,要做到这一点,您必须像这样分开您的关系:
public function adminProfile {
return $this->hasOne('App\AdminProfile');
}
public function companyProfile {
return $this->hasOne('App\CompanyProfile');
}
public function teacherProfile {
return $this->hasOne('App\TeacherProfile');
}
public function studentProfile {
return $this->hasOne('App\StudentProfile');
}
public function profile() {
switch ($this->type) {
case 'other':
return $this->adminProfile();
break;
case 'company':
return $this->companyProfile();
break;
case 'teacher':
return $this->teacherProfile();
break;
case 'student':
return $this->studentProfile();
break;
default:
throw new Exception('Unknown Type: '. $this->type);
}
}
然后得到这样的结果:
$students = User::where('type', 'student')->whereHas('studentProfile', function ($q) use($request) {
$filter = explode($request -> filter, ',');
$q -> where ($filter[0], @$filter[1]);
});
$teachers = User::where('type', 'teacher')->whereHas('teacherProfile', function ($q) use($request) {
$filter = explode($request -> filter, ',');
$q -> where ($filter[0], @$filter[1]);
});
$company = User::where('type', 'company')->whereHas('companyProfile', function ($q) use($request) {
$filter = explode($request -> filter, ',');
$q -> where ($filter[0], @$filter[1]);
});
但是,如果您可以使用多态关系,它们正是出于这个原因而创建的,并且会让事情变得容易得多。
"Polymorphic relations allow a model to belong to more than one other model on a single association." - Laravel 了解多态关系的工作原理,并添加了对所有 eloquent 函数的支持。
http://laravel.com/docs/5.1/eloquent-relationships#polymorphic-relations
我已经尝试解决这个问题 3 天了,但没有找到任何解决方案。
我在用户 table 和他们的个人资料 admin_profile、teacher_profile、student_profile 和 company_pofile 之间建立了有条件的一对一关系
用户模型中的关系如下所示:
function profile() {
switch ($this -> type) {
case 'other':
return $this -> hasOne('App\AdminProfile');
break;
case 'company':
return $this -> hasOne('App\CompanyProfile');
break;
case 'teacher':
return $this -> hasOne('App\TeacherProfile');
break;
case 'student':
return $this -> hasOne('App\StudentProfile');
break;
}
}
并且由于它是有条件的,所以在我调用 "get" 方法或其兄弟姐妹之一之前,预加载将不起作用。所以我使用 "load" 来获取这样的用户配置文件:
function getUser($id) {
$user = User::find($id) -> load('profile');
return response() -> json($user);
}
现在的问题是我想根据个人资料中的数据搜索用户,所以我这样做了:
if($request -> has('filter')) {
$users -> whereHas('profile', function ($q) use($request) {
$filter = explode($request -> filter, ',');
$q -> where ($filter[0], @$filter[1]);
});
}
当然因为条件关系,预加载是行不通的,这里是错误信息:
FatalErrorException in Builder.php line 580: Call to a member function getRelationCountQuery() on null
我自己也走过这条路,很痛苦。我强烈建议您改用 Laravel 的多态关系。如果不能,处理此问题的最佳方法是对每种关系类型进行单独查询。但是,要做到这一点,您必须像这样分开您的关系:
public function adminProfile {
return $this->hasOne('App\AdminProfile');
}
public function companyProfile {
return $this->hasOne('App\CompanyProfile');
}
public function teacherProfile {
return $this->hasOne('App\TeacherProfile');
}
public function studentProfile {
return $this->hasOne('App\StudentProfile');
}
public function profile() {
switch ($this->type) {
case 'other':
return $this->adminProfile();
break;
case 'company':
return $this->companyProfile();
break;
case 'teacher':
return $this->teacherProfile();
break;
case 'student':
return $this->studentProfile();
break;
default:
throw new Exception('Unknown Type: '. $this->type);
}
}
然后得到这样的结果:
$students = User::where('type', 'student')->whereHas('studentProfile', function ($q) use($request) {
$filter = explode($request -> filter, ',');
$q -> where ($filter[0], @$filter[1]);
});
$teachers = User::where('type', 'teacher')->whereHas('teacherProfile', function ($q) use($request) {
$filter = explode($request -> filter, ',');
$q -> where ($filter[0], @$filter[1]);
});
$company = User::where('type', 'company')->whereHas('companyProfile', function ($q) use($request) {
$filter = explode($request -> filter, ',');
$q -> where ($filter[0], @$filter[1]);
});
但是,如果您可以使用多态关系,它们正是出于这个原因而创建的,并且会让事情变得容易得多。
"Polymorphic relations allow a model to belong to more than one other model on a single association." - Laravel 了解多态关系的工作原理,并添加了对所有 eloquent 函数的支持。
http://laravel.com/docs/5.1/eloquent-relationships#polymorphic-relations