tp6 hasOneThrough 远程一对一关联查询,hasWhere()条件查询问题记录(日常记录)

问题描述

  • 在远程一对一查询用 hasWhere() 进行关联模型的条件查询时,可能会出现报错 无法查询的问题,例如下图
  • 在这里插入图片描述

问题分析

由于hasOneThrough 是继承 hasManyThrough,因此会直接使用 hasManyThrough 中的
hasWhere() 方法,

/**
     * 根据关联条件查询当前模型
     * @access public
     * @param  mixed  $where 查询条件(数组或者闭包)
     * @param  mixed  $fields 字段
     * @param  string $joinType JOIN类型
     * @param  Query  $query    Query对象
     * @return Query
     */
    public function hasWhere($where = [], $fields = null, $joinType = '', Query $query = null): Query
    {
        $model        = Str::snake(class_basename($this->parent));
        $throughTable = $this->through->getTable();
        $pk           = $this->throughPk;
        $throughKey   = $this->throughKey;
        $modelTable   = (new $this->model)->getTable();

        if (is_array($where)) {
            $this->getQueryWhere($where, $modelTable);
        } elseif ($where instanceof Query) {
            $where->via($modelTable);
        } elseif ($where instanceof Closure) {
            $where($this->query->via($modelTable));
            $where = $this->query;
        }

        $fields     = $this->getRelationQueryFields($fields, $model);
        $softDelete = $this->query->getOptions('soft_delete');
        $query      = $query ?: $this->parent->db();

        return $query->alias($model)
            ->join($throughTable, $throughTable . '.' . $this->foreignKey . '=' . $model . '.' . $this->localKey)
            ->join($modelTable, $modelTable . '.' . $throughKey . '=' . $throughTable . '.' . $this->throughPk, $joinType)
            ->when($softDelete, function ($query) use ($softDelete, $modelTable) {
                $query->where($modelTable . strstr($softDelete[0], '.'), '=' == $softDelete[1][0] ? $softDelete[1][1] : null);
            })
            ->group($modelTable . '.' . $this->throughKey)
            ->where($where)
            ->field($fields);
    }
  • 这可能不适用于我们的 远程一对一 hasOneThrough 的使用,因此需要修改一下

解决方法

这里直接拷贝上面hasManyThrough 的 hasWhere() 方法到 hasOneTrough,具体文件路径如下

  • hasManyThrough: vendor\topthink\think-orm\src\model\relation\HasManyThrough.php
  • hasOneThrough: vendor\topthink\think-orm\src\model\relation\HasOneThrough.php

接下来修改hasOneThrough 里刚刚复制的 hasWhere 方法,或者直接复制下面修改好的方法也可以

/**
     * 根据关联条件查询当前模型
     * @access public
     * @param  mixed  $where 查询条件(数组或者闭包)
     * @param  mixed  $fields 字段
     * @param  string $joinType JOIN类型
     * @param  Query  $query    Query对象
     * @return Query
     */
    public function hasWhere($where = [], $fields = null, $joinType = '', Query $query = null): Query
    {
        $model        = Str::snake(class_basename($this->parent));  // "当前模型"
        $throughTable = $this->through->getTable();                 // "中间模型"
        $pk           = $this->throughPk;
        $throughKey   = $this->throughKey;
        $modelTable   = (new $this->model)->getTable();             // "关联模型"

        if (is_array($where)) {
            $this->getQueryWhere($where, $modelTable);
        } elseif ($where instanceof Query) {
            $where->via($modelTable);
        } elseif ($where instanceof Closure) {
            $where($this->query->via($modelTable));
            $where = $this->query;
        }

        $fields     = $this->getRelationQueryFields($fields, $model);
        $softDelete = $this->query->getOptions('soft_delete');
        $query      = $query ?: $this->parent->db();

		// start 修改的地方
        $alias = [
            $throughTable   => $throughTable,		// "中间模型"
            $modelTable     => $modelTable,			// "关联模型"
            $model          => $model				// "当前模型"
        ];
        return $query
            ->alias($alias)				// 这里替换掉原来的$model, 这是为了解决开头的那个报错问题
            ->join($throughTable, $throughTable . '.' . $this->foreignKey . '=' . $model . '.' . $this->localKey)
            ->join($modelTable, $modelTable . '.' . $throughKey . '=' . $throughTable . '.' . $this->throughPk, $joinType)
            ->when($softDelete, function ($query) use ($softDelete, $modelTable) {
                $query->where($modelTable . strstr($softDelete[0], '.'), '=' == $softDelete[1][0] ? $softDelete[1][1] : null);
            })
            // ->group($modelTable . '.' . $this->throughKey)	// 这里group的分组我们也用不到
            ->where($where);
            // ->field($fields);			// 这里去掉即可,我感觉没什么用,毕竟字段控制可以直接用visible控制
         // end 
    }

这里说下修改的地方(虽然代码里写明,但不排除有不看的0_0)

  • 修改1:将原来的$model 替换成 $alias(对应参数“中间模型”,“关联模型”, “当前模型”)
    在这里插入图片描述

  • 修改2:其实也没啥修改的,也就去掉了点不要的(group 和 field)

  • 修改前
    修改前

  • 修改后
    修改后

到这就可以正常的使用hasWhere对关联模型的字段进行查询了,如有错漏,欢迎评论指正0_0

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值