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