【问题标题】:Making a join with Eloquent based on a list of ids根据 id 列表与 Eloquent 进行连接
【发布时间】:2015-07-04 08:07:57
【问题描述】:

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

wigs:
- id
- name
- type

heads:
- id
- name

heads_wigs:
- head_id
- wig_id

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

  • wigtype
  • headid 的数组

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

【问题讨论】:

    标签: php mysql join orm eloquent


    【解决方案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;
    

    这样,返回的 wig 对象将有一个匹配的头部 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();
    

    这应该会给你你需要的结果。

    【讨论】:

    • 这不是我的目标。我会试着用一句话来改写它:get all wigs with type=wig_type that have a belongsToMany relationship with the heads [1,2,3,5,6,8,9]。我想通过执行单个查询来结束 wigs 的集合。
    • 我已经修改了答案。
    • 太棒了,谢谢!这正是我一直在寻找的。 whereHas 方法对我来说似乎是最合乎逻辑的,现在我只需要检查哪个性能最好。
    猜你喜欢
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-11
    • 1970-01-01
    • 1970-01-01
    • 2017-02-19
    相关资源
    最近更新 更多