根据 ID 列表与 Eloquent 进行连接

Making a join with Eloquent based on a list of ids

我已经建立了两个 Eloquent 模型,在两个方向上都有 belongsToMany 关系。这工作得很好,但现在我需要在关系中进行更详细的查询。为了简单起见,假设表格有以下列:

wigs:
- id
- name
- type

heads:
- id
- name

heads_wigs:
- head_id
- wig_id

现在我需要在给定的 head id 的列表中使用给定的 type 获取一系列 wigs。所以我有:

我在 laravel 之外使用 Eloquent,所以我想开始在模型上构建 ORM 查询。类似于:

Wig::where( 'type', $type )-> ... //here the code to make the join on head id's

这是我对 SQL 的理解不足的地方,但我想这应该不难实现。

更新:

换句话说:get all wigs with type=wig_type that have a belongsToMany relationship with the heads [1,2,3,5,6,8,9]。我想通过执行单个查询得到 wigs 的集合。

你可以这样做

Head::whereIn('id', $head_id_array)->load(['wig' => function($query) use ($wig_type) {
        $query->where('type', $wig_type);
}])->get();

Wig::where('type', $wig_type)->load(['heads' => function($query) use ($head_id_array) {
    $query->whereIn('id', $head_id_array);
}])->get();

如果我理解正确的话。

$wig = Wig::where('type', $wig_type)->get();
$heads = $wig->heads()->whereIn('id', $head_id_array)->get();
$matching_head_ids = $heads->lists('id');
$wig->matching_head_ids = $matching_head_ids;

这样,返回的假发对象将有一个匹配的头部 ID 数组。

你可以把它放在你的假发模型的方法中:

class Wig extends Eloquent {
    public function heads()
    {
        return $this->belongsToMany('Head');
    }

    /**
     * @param array $head_ids    Provided head id array
     * @return array             Array of this wigs head id's which match the provided head ids
     */
    public function matchingHeadIds($head_ids)
    {
        return $this->heads()->whereIn('id', $head_ids)->get()->lists('id');
    }
}

然后像这样使用它

$wig = Wig::where('type', $wig_type);
$wig->matchingHeadIds($head_ids);

编辑

对于像 eloquent 这样的 ORM 来说,这不是一项简单的任务,因为它将每条记录视为 table 中的一行,所以这样的事情是行不通的:

$wigs = Head::whereIn('id', $head_ids)->wigs()->where('type', $wig_type)->get();

有一个 whereHas 方法可用,您可以像这样使用它:

Wig::where('type', $wig_type)->whereHas('heads', function ($query) use ($head_ids) {
    $query->whereIn('id', $head_ids);
})->get();

这应该会为您提供所需的结果。