BelongsToMany.php 19.7 KB
Newer Older
D
devil_gong 已提交
1 2 3 4
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
D
Devil 已提交
5
// | Copyright (c) 2006~2019 http://thinkphp.cn All rights reserved.
D
devil_gong 已提交
6 7 8 9 10 11 12 13
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------

namespace think\model\relation;

D
Devil 已提交
14
use Closure;
D
devil_gong 已提交
15
use think\Collection;
D
Devil 已提交
16 17 18
use think\db\BaseQuery as Query;
use think\db\exception\DbException as Exception;
use think\db\Raw;
D
devil_gong 已提交
19 20 21
use think\Model;
use think\model\Pivot;
use think\model\Relation;
D
Devil 已提交
22
use think\Paginator;
D
devil_gong 已提交
23

D
Devil 已提交
24 25 26
/**
 * 多对多关联类
 */
D
devil_gong 已提交
27 28
class BelongsToMany extends Relation
{
D
Devil 已提交
29 30 31 32
    /**
     * 中间表表名
     * @var string
     */
D
devil_gong 已提交
33
    protected $middle;
D
Devil 已提交
34 35 36 37 38

    /**
     * 中间表模型名称
     * @var string
     */
D
devil_gong 已提交
39
    protected $pivotName;
D
Devil 已提交
40 41 42 43 44

    /**
     * 中间表模型对象
     * @var Pivot
     */
D
devil_gong 已提交
45 46
    protected $pivot;

D
Devil 已提交
47 48 49 50 51 52
    /**
     * 中间表数据名称
     * @var string
     */
    protected $pivotDataName = 'pivot';

D
devil_gong 已提交
53 54 55 56 57
    /**
     * 架构函数
     * @access public
     * @param  Model  $parent     上级模型对象
     * @param  string $model      模型名
D
Devil 已提交
58
     * @param  string $middle     中间表/模型名
D
devil_gong 已提交
59 60 61
     * @param  string $foreignKey 关联模型外键
     * @param  string $localKey   当前模型关联键
     */
D
Devil 已提交
62
    public function __construct(Model $parent, string $model, string $middle, string $foreignKey, string $localKey)
D
devil_gong 已提交
63 64 65 66 67 68
    {
        $this->parent     = $parent;
        $this->model      = $model;
        $this->foreignKey = $foreignKey;
        $this->localKey   = $localKey;

D
Devil 已提交
69 70 71
        if (false !== strpos($middle, '\\')) {
            $this->pivotName = $middle;
            $this->middle    = class_basename($middle);
D
devil_gong 已提交
72
        } else {
D
Devil 已提交
73
            $this->middle = $middle;
D
devil_gong 已提交
74 75 76 77 78 79 80 81 82 83 84 85
        }

        $this->query = (new $model)->db();
        $this->pivot = $this->newPivot();
    }

    /**
     * 设置中间表模型
     * @access public
     * @param  $pivot
     * @return $this
     */
D
Devil 已提交
86
    public function pivot(string $pivot)
D
devil_gong 已提交
87 88 89 90 91 92 93 94 95 96 97
    {
        $this->pivotName = $pivot;
        return $this;
    }

    /**
     * 设置中间表数据名称
     * @access public
     * @param  string $name
     * @return $this
     */
D
Devil 已提交
98
    public function name(string $name)
D
devil_gong 已提交
99 100 101 102 103 104 105 106
    {
        $this->pivotDataName = $name;
        return $this;
    }

    /**
     * 实例化中间表模型
     * @access public
D
Devil 已提交
107
     * @param  $data
D
devil_gong 已提交
108 109 110
     * @return Pivot
     * @throws Exception
     */
D
Devil 已提交
111
    protected function newPivot(array $data = []): Pivot
D
devil_gong 已提交
112
    {
D
Devil 已提交
113
        $class = $this->pivotName ?: Pivot::class;
D
devil_gong 已提交
114 115 116
        $pivot = new $class($data, $this->parent, $this->middle);

        if ($pivot instanceof Pivot) {
D
Devil 已提交
117 118 119
            return $pivot;
        } else {
            throw new Exception('pivot model must extends: \think\model\Pivot');
D
devil_gong 已提交
120 121 122 123 124 125 126 127
        }
    }

    /**
     * 合成中间表模型
     * @access protected
     * @param  array|Collection|Paginator $models
     */
D
Devil 已提交
128
    protected function hydratePivot(iterable $models)
D
devil_gong 已提交
129 130 131 132 133 134
    {
        foreach ($models as $model) {
            $pivot = [];

            foreach ($model->getData() as $key => $val) {
                if (strpos($key, '__')) {
D
Devil 已提交
135
                    [$name, $attr] = explode('__', $key, 2);
D
devil_gong 已提交
136 137 138 139 140 141 142 143

                    if ('pivot' == $name) {
                        $pivot[$attr] = $val;
                        unset($model->$key);
                    }
                }
            }

D
Devil 已提交
144
            $model->setRelation($this->pivotDataName, $this->newPivot($pivot));
D
devil_gong 已提交
145 146 147 148 149 150
        }
    }

    /**
     * 延迟获取关联数据
     * @access public
D
Devil 已提交
151 152
     * @param  array    $subRelation 子关联名
     * @param  Closure  $closure     闭包查询条件
D
devil_gong 已提交
153 154
     * @return Collection
     */
D
Devil 已提交
155
    public function getRelation(array $subRelation = [], Closure $closure = null): Collection
D
devil_gong 已提交
156
    {
D
devil_gong 已提交
157
        if ($closure) {
D
Devil 已提交
158
            $closure($this->getClosureType($closure));
D
devil_gong 已提交
159 160
        }

D
Devil 已提交
161 162 163 164
        $result = $this->relation($subRelation)
            ->select()
            ->setParent(clone $this->parent);

D
devil_gong 已提交
165 166 167 168 169 170 171 172 173 174 175
        $this->hydratePivot($result);

        return $result;
    }

    /**
     * 重载select方法
     * @access public
     * @param  mixed $data
     * @return Collection
     */
D
Devil 已提交
176
    public function select($data = null): Collection
D
devil_gong 已提交
177
    {
D
Devil 已提交
178 179
        $this->baseQuery();
        $result = $this->query->select($data);
D
devil_gong 已提交
180 181 182 183 184 185 186 187
        $this->hydratePivot($result);

        return $result;
    }

    /**
     * 重载paginate方法
     * @access public
D
Devil 已提交
188 189
     * @param  int|array $listRows
     * @param  int|bool  $simple
D
devil_gong 已提交
190 191
     * @return Paginator
     */
D
Devil 已提交
192
    public function paginate($listRows = null, $simple = false): Paginator
D
devil_gong 已提交
193
    {
D
Devil 已提交
194 195
        $this->baseQuery();
        $result = $this->query->paginate($listRows, $simple);
D
devil_gong 已提交
196 197 198 199 200 201 202 203 204 205 206 207 208
        $this->hydratePivot($result);

        return $result;
    }

    /**
     * 重载find方法
     * @access public
     * @param  mixed $data
     * @return Model
     */
    public function find($data = null)
    {
D
Devil 已提交
209 210 211 212
        $this->baseQuery();
        $result = $this->query->find($data);

        if ($result && !$result->isEmpty()) {
D
devil_gong 已提交
213 214 215 216 217 218 219 220 221 222 223 224 225
            $this->hydratePivot([$result]);
        }

        return $result;
    }

    /**
     * 根据关联条件查询当前模型
     * @access public
     * @param  string  $operator 比较操作符
     * @param  integer $count    个数
     * @param  string  $id       关联表的统计字段
     * @param  string  $joinType JOIN类型
D
Devil 已提交
226 227
     * @param  Query   $query    Query对象
     * @return Model
D
devil_gong 已提交
228
     */
D
Devil 已提交
229
    public function has(string $operator = '>=', $count = 1, $id = '*', string $joinType = 'INNER', Query $query = null)
D
devil_gong 已提交
230 231 232 233 234 235 236
    {
        return $this->parent;
    }

    /**
     * 根据关联条件查询当前模型
     * @access public
D
Devil 已提交
237 238 239 240
     * @param  mixed  $where 查询条件(数组或者闭包)
     * @param  mixed  $fields 字段
     * @param  string $joinType JOIN类型
     * @param  Query  $query    Query对象
D
devil_gong 已提交
241 242 243
     * @return Query
     * @throws Exception
     */
D
Devil 已提交
244
    public function hasWhere($where = [], $fields = null, string $joinType = '', Query $query = null)
D
devil_gong 已提交
245 246 247 248 249 250 251
    {
        throw new Exception('relation not support: hasWhere');
    }

    /**
     * 设置中间表的查询条件
     * @access public
D
Devil 已提交
252 253 254
     * @param  string $field
     * @param  string $op
     * @param  mixed  $condition
D
devil_gong 已提交
255 256 257 258 259 260 261 262 263 264 265
     * @return $this
     */
    public function wherePivot($field, $op = null, $condition = null)
    {
        $this->query->where('pivot.' . $field, $op, $condition);
        return $this;
    }

    /**
     * 预载入关联查询(数据集)
     * @access public
D
Devil 已提交
266 267 268 269 270
     * @param  array   $resultSet   数据集
     * @param  string  $relation    当前关联名
     * @param  array   $subRelation 子关联名
     * @param  Closure $closure     闭包
     * @param  array   $cache       关联缓存
D
devil_gong 已提交
271 272
     * @return void
     */
D
Devil 已提交
273
    public function eagerlyResultSet(array &$resultSet, string $relation, array $subRelation, Closure $closure = null, array $cache = []): void
D
devil_gong 已提交
274
    {
D
Devil 已提交
275 276 277
        $localKey = $this->localKey;
        $pk       = $resultSet[0]->getPk();
        $range    = [];
D
devil_gong 已提交
278 279 280 281 282 283 284 285 286 287 288 289

        foreach ($resultSet as $result) {
            // 获取关联外键列表
            if (isset($result->$pk)) {
                $range[] = $result->$pk;
            }
        }

        if (!empty($range)) {
            // 查询关联数据
            $data = $this->eagerlyManyToMany([
                ['pivot.' . $localKey, 'in', $range],
D
Devil 已提交
290
            ], $subRelation, $closure, $cache);
D
devil_gong 已提交
291 292 293 294 295 296 297

            // 关联数据封装
            foreach ($resultSet as $result) {
                if (!isset($data[$result->$pk])) {
                    $data[$result->$pk] = [];
                }

D
Devil 已提交
298
                $result->setRelation($relation, $this->resultSetBuild($data[$result->$pk], clone $this->parent));
D
devil_gong 已提交
299 300 301 302 303 304 305
            }
        }
    }

    /**
     * 预载入关联查询(单个数据)
     * @access public
D
Devil 已提交
306 307 308 309 310
     * @param  Model   $result      数据对象
     * @param  string  $relation    当前关联名
     * @param  array   $subRelation 子关联名
     * @param  Closure $closure     闭包
     * @param  array   $cache       关联缓存
D
devil_gong 已提交
311 312
     * @return void
     */
D
Devil 已提交
313
    public function eagerlyResult(Model $result, string $relation, array $subRelation, Closure $closure = null, array $cache = []): void
D
devil_gong 已提交
314 315 316 317 318 319 320 321
    {
        $pk = $result->getPk();

        if (isset($result->$pk)) {
            $pk = $result->$pk;
            // 查询管理数据
            $data = $this->eagerlyManyToMany([
                ['pivot.' . $this->localKey, '=', $pk],
D
Devil 已提交
322
            ], $subRelation, $closure, $cache);
D
devil_gong 已提交
323 324 325 326 327 328

            // 关联数据封装
            if (!isset($data[$pk])) {
                $data[$pk] = [];
            }

D
Devil 已提交
329
            $result->setRelation($relation, $this->resultSetBuild($data[$pk], clone $this->parent));
D
devil_gong 已提交
330 331 332 333 334 335
        }
    }

    /**
     * 关联统计
     * @access public
D
Devil 已提交
336 337 338 339 340
     * @param  Model   $result  数据对象
     * @param  Closure $closure 闭包
     * @param  string  $aggregate 聚合查询方法
     * @param  string  $field 字段
     * @param  string  $name 统计字段别名
D
devil_gong 已提交
341 342
     * @return integer
     */
D
Devil 已提交
343
    public function relationCount(Model $result, Closure $closure = null, string $aggregate = 'count', string $field = '*', string &$name = null): float
D
devil_gong 已提交
344 345 346 347 348 349 350 351 352
    {
        $pk = $result->getPk();

        if (!isset($result->$pk)) {
            return 0;
        }

        $pk = $result->$pk;

D
devil_gong 已提交
353
        if ($closure) {
D
Devil 已提交
354
            $closure($this->getClosureType($closure), $name);
D
devil_gong 已提交
355 356 357 358 359 360 361 362 363 364
        }

        return $this->belongsToManyQuery($this->foreignKey, $this->localKey, [
            ['pivot.' . $this->localKey, '=', $pk],
        ])->$aggregate($field);
    }

    /**
     * 获取关联统计子查询
     * @access public
D
Devil 已提交
365 366 367 368 369
     * @param  Closure $closure 闭包
     * @param  string  $aggregate 聚合查询方法
     * @param  string  $field 字段
     * @param  string  $name 统计字段别名
     * @return string
D
devil_gong 已提交
370
     */
D
Devil 已提交
371
    public function getRelationCountQuery(Closure $closure = null, string $aggregate = 'count', string $field = '*', string &$name = null): string
D
devil_gong 已提交
372
    {
D
devil_gong 已提交
373
        if ($closure) {
D
Devil 已提交
374
            $closure($this->getClosureType($closure), $name);
D
devil_gong 已提交
375 376 377 378
        }

        return $this->belongsToManyQuery($this->foreignKey, $this->localKey, [
            [
D
Devil 已提交
379
                'pivot.' . $this->localKey, 'exp', new Raw('=' . $this->parent->db(false)->getTable() . '.' . $this->parent->getPk()),
D
devil_gong 已提交
380 381 382 383 384 385 386
            ],
        ])->fetchSql()->$aggregate($field);
    }

    /**
     * 多对多 关联模型预查询
     * @access protected
D
Devil 已提交
387 388 389 390
     * @param  array   $where       关联预查询条件
     * @param  array   $subRelation 子关联
     * @param  Closure $closure     闭包
     * @param  array   $cache       关联缓存
D
devil_gong 已提交
391 392
     * @return array
     */
D
Devil 已提交
393
    protected function eagerlyManyToMany(array $where, array $subRelation = [], Closure $closure = null, array $cache = []): array
D
devil_gong 已提交
394
    {
D
devil_gong 已提交
395
        if ($closure) {
D
Devil 已提交
396
            $closure($this->getClosureType($closure));
D
devil_gong 已提交
397 398
        }

D
Devil 已提交
399
        // 预载入关联查询 支持嵌套预载入
D
devil_gong 已提交
400 401
        $list = $this->belongsToManyQuery($this->foreignKey, $this->localKey, $where)
            ->with($subRelation)
D
Devil 已提交
402
            ->cache($cache[0] ?? false, $cache[1] ?? null, $cache[2] ?? null)
D
devil_gong 已提交
403 404 405 406 407 408 409 410
            ->select();

        // 组装模型数据
        $data = [];
        foreach ($list as $set) {
            $pivot = [];
            foreach ($set->getData() as $key => $val) {
                if (strpos($key, '__')) {
D
Devil 已提交
411
                    [$name, $attr] = explode('__', $key, 2);
D
devil_gong 已提交
412 413 414 415 416 417
                    if ('pivot' == $name) {
                        $pivot[$attr] = $val;
                        unset($set->$key);
                    }
                }
            }
D
Devil 已提交
418
            $key = $pivot[$this->localKey];
D
devil_gong 已提交
419

D
Devil 已提交
420 421 422
            if ($this->withLimit && isset($data[$key]) && count($data[$key]) >= $this->withLimit) {
                continue;
            }
D
devil_gong 已提交
423

D
Devil 已提交
424 425 426
            $set->setRelation($this->pivotDataName, $this->newPivot($pivot));

            $data[$key][] = $set;
D
devil_gong 已提交
427 428 429 430 431 432 433 434
        }

        return $data;
    }

    /**
     * BELONGS TO MANY 关联查询
     * @access protected
D
Devil 已提交
435 436 437
     * @param  string $foreignKey 关联模型关联键
     * @param  string $localKey   当前模型关联键
     * @param  array  $condition  关联查询条件
D
devil_gong 已提交
438 439
     * @return Query
     */
D
Devil 已提交
440
    protected function belongsToManyQuery(string $foreignKey, string $localKey, array $condition = []): Query
D
devil_gong 已提交
441 442
    {
        // 关联查询封装
D
Devil 已提交
443 444 445
        if (empty($this->baseQuery)) {
            $tableName = $this->query->getTable();
            $table     = $this->pivot->db()->getTable();
D
Devil 已提交
446 447 448 449 450 451

            if ($this->withoutField) {
                $this->query->withoutField($this->withoutField);
            }

            $fields = $this->getQueryFields($tableName);
D
devil_gong 已提交
452

D
Devil 已提交
453 454 455
            if ($this->withLimit) {
                $this->query->limit($this->withLimit);
            }
D
devil_gong 已提交
456

D
Devil 已提交
457 458 459 460
            $this->query
                ->field($fields)
                ->tableField(true, $table, 'pivot', 'pivot__')
                ->join([$table => 'pivot'], 'pivot.' . $foreignKey . '=' . $tableName . '.' . $this->query->getPk())
D
devil_gong 已提交
461
                ->where($condition);
D
Devil 已提交
462

D
devil_gong 已提交
463 464
        }

D
Devil 已提交
465
        return $this->query;
D
devil_gong 已提交
466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483
    }

    /**
     * 保存(新增)当前关联数据对象
     * @access public
     * @param  mixed $data  数据 可以使用数组 关联模型对象 和 关联对象的主键
     * @param  array $pivot 中间表额外数据
     * @return array|Pivot
     */
    public function save($data, array $pivot = [])
    {
        // 保存关联表/中间表数据
        return $this->attach($data, $pivot);
    }

    /**
     * 批量保存当前关联数据对象
     * @access public
D
Devil 已提交
484 485 486
     * @param  iterable $dataSet   数据集
     * @param  array    $pivot     中间表额外数据
     * @param  bool     $samePivot 额外数据是否相同
D
devil_gong 已提交
487 488
     * @return array|false
     */
D
Devil 已提交
489
    public function saveAll(iterable $dataSet, array $pivot = [], bool $samePivot = false)
D
devil_gong 已提交
490 491 492 493 494
    {
        $result = [];

        foreach ($dataSet as $key => $data) {
            if (!$samePivot) {
D
Devil 已提交
495
                $pivotData = $pivot[$key] ?? [];
D
devil_gong 已提交
496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513
            } else {
                $pivotData = $pivot;
            }

            $result[] = $this->attach($data, $pivotData);
        }

        return empty($result) ? false : $result;
    }

    /**
     * 附加关联的一个中间表数据
     * @access public
     * @param  mixed $data  数据 可以使用数组、关联模型对象 或者 关联对象的主键
     * @param  array $pivot 中间表额外数据
     * @return array|Pivot
     * @throws Exception
     */
D
Devil 已提交
514
    public function attach($data, array $pivot = [])
D
devil_gong 已提交
515 516 517 518 519 520 521 522 523 524 525 526 527 528
    {
        if (is_array($data)) {
            if (key($data) === 0) {
                $id = $data;
            } else {
                // 保存关联表数据
                $model = new $this->model;
                $id    = $model->insertGetId($data);
            }
        } elseif (is_numeric($data) || is_string($data)) {
            // 根据关联表主键直接写入中间表
            $id = $data;
        } elseif ($data instanceof Model) {
            // 根据关联表主键直接写入中间表
D
Devil 已提交
529
            $id = $data->getKey();
D
devil_gong 已提交
530 531
        }

D
Devil 已提交
532
        if (!empty($id)) {
D
devil_gong 已提交
533
            // 保存中间表数据
D
Devil 已提交
534
            $pivot[$this->localKey] = $this->parent->getKey();
D
devil_gong 已提交
535

D
Devil 已提交
536
            $ids = (array) $id;
D
devil_gong 已提交
537 538 539 540
            foreach ($ids as $id) {
                $pivot[$this->foreignKey] = $id;
                $this->pivot->replace()
                    ->exists(false)
D
Devil 已提交
541
                    ->data([])
D
devil_gong 已提交
542
                    ->save($pivot);
D
Devil 已提交
543
                $result[] = $this->newPivot($pivot);
D
devil_gong 已提交
544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559
            }

            if (count($result) == 1) {
                // 返回中间表模型对象
                $result = $result[0];
            }

            return $result;
        } else {
            throw new Exception('miss relation data');
        }
    }

    /**
     * 判断是否存在关联数据
     * @access public
D
Devil 已提交
560 561
     * @param  mixed $data 数据 可以使用关联模型对象 或者 关联对象的主键
     * @return Pivot|false
D
devil_gong 已提交
562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585
     */
    public function attached($data)
    {
        if ($data instanceof Model) {
            $id = $data->getKey();
        } else {
            $id = $data;
        }

        $pivot = $this->pivot
            ->where($this->localKey, $this->parent->getKey())
            ->where($this->foreignKey, $id)
            ->find();

        return $pivot ?: false;
    }

    /**
     * 解除关联的一个中间表数据
     * @access public
     * @param  integer|array $data        数据 可以使用关联对象的主键
     * @param  bool          $relationDel 是否同时删除关联表数据
     * @return integer
     */
D
Devil 已提交
586
    public function detach($data = null, bool $relationDel = false): int
D
devil_gong 已提交
587 588 589 590 591 592 593 594
    {
        if (is_array($data)) {
            $id = $data;
        } elseif (is_numeric($data) || is_string($data)) {
            // 根据关联表主键直接写入中间表
            $id = $data;
        } elseif ($data instanceof Model) {
            // 根据关联表主键直接写入中间表
D
Devil 已提交
595
            $id = $data->getKey();
D
devil_gong 已提交
596 597 598
        }

        // 删除中间表数据
D
Devil 已提交
599 600
        $pivot   = [];
        $pivot[] = [$this->localKey, '=', $this->parent->getKey()];
D
devil_gong 已提交
601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623

        if (isset($id)) {
            $pivot[] = [$this->foreignKey, is_array($id) ? 'in' : '=', $id];
        }

        $result = $this->pivot->where($pivot)->delete();

        // 删除关联表数据
        if (isset($id) && $relationDel) {
            $model = $this->model;
            $model::destroy($id);
        }

        return $result;
    }

    /**
     * 数据同步
     * @access public
     * @param  array $ids
     * @param  bool  $detaching
     * @return array
     */
D
Devil 已提交
624
    public function sync(array $ids, bool $detaching = true): array
D
devil_gong 已提交
625 626 627 628 629 630 631 632
    {
        $changes = [
            'attached' => [],
            'detached' => [],
            'updated'  => [],
        ];

        $current = $this->pivot
D
Devil 已提交
633
            ->where($this->localKey, $this->parent->getKey())
D
devil_gong 已提交
634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669
            ->column($this->foreignKey);

        $records = [];

        foreach ($ids as $key => $value) {
            if (!is_array($value)) {
                $records[$value] = [];
            } else {
                $records[$key] = $value;
            }
        }

        $detach = array_diff($current, array_keys($records));

        if ($detaching && count($detach) > 0) {
            $this->detach($detach);
            $changes['detached'] = $detach;
        }

        foreach ($records as $id => $attributes) {
            if (!in_array($id, $current)) {
                $this->attach($id, $attributes);
                $changes['attached'][] = $id;
            } elseif (count($attributes) > 0 && $this->attach($id, $attributes)) {
                $changes['updated'][] = $id;
            }
        }

        return $changes;
    }

    /**
     * 执行基础查询(仅执行一次)
     * @access protected
     * @return void
     */
D
Devil 已提交
670
    protected function baseQuery(): void
D
devil_gong 已提交
671
    {
D
Devil 已提交
672 673 674 675 676 677 678 679 680 681 682 683
        if (empty($this->baseQuery)) {
            $foreignKey = $this->foreignKey;
            $localKey   = $this->localKey;

            // 关联查询
            if (null === $this->parent->getKey()) {
                $condition = ['pivot.' . $localKey, 'exp', new Raw('=' . $this->parent->getTable() . '.' . $this->parent->getPk())];
            } else {
                $condition = ['pivot.' . $localKey, '=', $this->parent->getKey()];
            }

            $this->belongsToManyQuery($foreignKey, $localKey, [$condition]);
D
devil_gong 已提交
684 685 686 687 688 689

            $this->baseQuery = true;
        }
    }

}