根据ID列表与Eloquent建立联接

时间:2015-04-25 18:43:29

标签: php mysql join orm eloquent

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

wigs:
- id
- name
- type

heads:
- id
- name

heads_wigs:
- head_id
- wig_id

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

  • wig type
  • 包含head id
  • 的数组

我在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的集合。

1 个答案:

答案 0 :(得分:1)

你可以做这样的事情

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来说不是一个简单的任务,因为它将每条记录视为表中的一行,所以这样的东西不起作用:

$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();

可以为您提供所需的结果。