php - 使用 Laravel 的 ORM Eloquent 通过多个数据透视表查询对象

标签 php mysql laravel eloquent relationship

我想做的是通过多个关系(数据透视表)检索数据。 我有三个数据库表

用户城市工作

它们是这样 build 的(它们不是,只是为了让你一瞥)

用户表
id int(11) PK,自增
名称 varchar(255)

城市表
id int(11) PK,自增
名称 varchar(255)

工作表
id int(11) PK,自增
名称 varchar(255)


现在我有了数据透视表,因为它们是多对多关系。我得到了表 city_userjob_user

CityUser 表
city_id int(11),
user_id int(11)

JobUser 表
job_id int(11),
user_id int(11)

在每个类(UserCityJob)中,我得到了用 belongsToMany 定义的关系方法。

城市级

/**
 * Defines the relation between the city and its users
 *
 * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
 */
public function users()
{
    return $this->belongsToMany(User::class, 'city_user');
}

用户类

/**
 * Defines the relation between the user and its cities
 *
 * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
 */
public function cities()
{
    return $this->belongsToMany(City::class, 'city_user');
}

jobs 表也是如此。我现在想做的是让所有在特定城市并拥有特定工作的用户。

假设我想查询居住在 ID 为 5 的城市并拥有 ID 为 10 的工作的所有用户。

建立一段关系相当容易

$users = City::find(5)->users;

$users = Job::find(10)->users;

但是,在这种情况下,我如何为多个关系实现这一点?我试过这样做

$users = City::find(10)->with(['users' => function($query) use ($jobId) {
    // Here I'm stuck. I wouldn't know how to query further? Maybe like this
    return $query->with('jobs')->whereJobId($jobId);
}]);

但是,当我这样做时,我得到了 0 个结果,所以肯定有问题。有什么想法吗?

我遇到了一个错误

Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42S22]: Column not found: 1054 Unknown column 'job_id' in 'where clause'' in

我也这样试过(在 with(['consultants']) 中)

$query->with(['jobs' => function ($query) use ($jobId) {
    $query->whereJobId($jobId);
}]);

但这看起来不对。此外,我得到了 CitiesCollection,但我需要一个 Users

然后就这样(临时)累了

$users = User::with(['cities' => function ($query) use($cityId) {
    /** @var \Illuminate\Database\Eloquent\Relations\BelongsToMany $query */
    $query->wherePivot('city_id', $cityId);
}])->get();

但是,然后我得到了所有用户,而不仅仅是那些用户,这更加令人困惑,因为文档说


Sometimes you may wish to eager load a relationship, but also specify additional query constraints for the eager loading query. Here's an example:

$users = App\User::with(['posts' => function ($query) {
    $query->where('title', 'like', '%first%');
}])->get();

In this example, Eloquent will only eager load posts that if the post's title column contains the word first. Of course, you may call other query builder to further customize the eager loading operation:

但为什么它不起作用呢?

最佳答案

您可以通过这种方式解决 fatal error :

$users = City::find(10)->with(['users.jobs', function($query) use ($jobId) {
        $query->whereJobId($jobId);
    });
}]);

但这不会过滤特定工作 ID 的用户。例如,我们有两个 ID 为 1#2 的用户。用户 1 与工作 10 相关,而用户 2 不相关。上面的代码将为您提供 $jobId = 10 的两个用户,因为用户查询将在没有任何作业过滤器的情况下首先执行,作业查询将在用户查询之后执行。

您必须使用查询构建器的 join() 方法:

$users = User::join('job_user', 'users.id', '=', 'job_user.user_id')
    ->join('city_user', 'users.id', '=', 'city_user.user_id')
    ->where('job_user.job_id', $jobId)
    ->where('city_user.city_id', $cityId)
    ->get();

关于php - 使用 Laravel 的 ORM Eloquent 通过多个数据透视表查询对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34222087/

相关文章:

php - IF ELSE 不在 MySQL 中工作?

mysql - 外键遇到问题

javascript - 为什么在我的 View 中看不到我的总计?

PhpMyAdmin 外键约束不起作用

PHP - 写入数据库并在设定时间后删除

php - MySQL/PHP 中的递归处理

php - 由验证引起的 Laravel 路由中的重定向循环?

php - 如何使用 PHP 和 Swift 5 解析 JSON

php - 更新或插入,在 sql 中自动递增 int

php - xampp下php中的命名空间