改进多对多关联,支持中间表模型自定义 并且定义的时候不需要使用完整表名

This commit is contained in:
thinkphp
2017-03-17 18:52:19 +08:00
parent ade630d979
commit f4629107a2
2 changed files with 28 additions and 21 deletions

View File

@@ -35,8 +35,9 @@ class Pivot extends Model
} }
$this->parent = $parent; $this->parent = $parent;
if (is_null($this->name)) {
$this->table = $table; $this->name = $table;
}
} }
} }

View File

@@ -24,8 +24,9 @@ class BelongsToMany extends Relation
{ {
// 中间表表名 // 中间表表名
protected $middle; protected $middle;
// 中间表模型名称
// 中间表模型 protected $pivotName;
// 中间表模型对象
protected $pivot; protected $pivot;
/** /**
@@ -43,8 +44,13 @@ class BelongsToMany extends Relation
$this->model = $model; $this->model = $model;
$this->foreignKey = $foreignKey; $this->foreignKey = $foreignKey;
$this->localKey = $localKey; $this->localKey = $localKey;
$this->middle = $table; if (false === strpos($table, '\\')) {
$this->query = (new $model)->db(); $this->middle = $table;
} else {
$this->pivotName = $table;
}
$this->query = (new $model)->db();
$this->pivot = $this->newPivot();
} }
/** /**
@@ -54,7 +60,7 @@ class BelongsToMany extends Relation
*/ */
public function pivot($pivot) public function pivot($pivot)
{ {
$this->pivot = $pivot; $this->pivotName = $pivot;
return $this; return $this;
} }
@@ -63,9 +69,9 @@ class BelongsToMany extends Relation
* @param $data * @param $data
* @return mixed * @return mixed
*/ */
protected function newPivot($data) protected function newPivot($data = [])
{ {
$pivot = $this->pivot ?: '\\think\\model\\Pivot'; $pivot = $this->pivotName ?: '\\think\\model\\Pivot';
return new $pivot($this->parent, $data, $this->middle); return new $pivot($this->parent, $data, $this->middle);
} }
@@ -102,7 +108,7 @@ class BelongsToMany extends Relation
// 关联查询 // 关联查询
$pk = $this->parent->getPk(); $pk = $this->parent->getPk();
$condition['pivot.' . $localKey] = $this->parent->$pk; $condition['pivot.' . $localKey] = $this->parent->$pk;
return $this->belongsToManyQuery($middle, $foreignKey, $localKey, $condition); return $this->belongsToManyQuery($foreignKey, $localKey, $condition);
} }
/** /**
@@ -114,7 +120,7 @@ class BelongsToMany extends Relation
public function getRelation($subRelation = '', $closure = null) public function getRelation($subRelation = '', $closure = null)
{ {
if ($closure) { if ($closure) {
call_user_func_array($closure, [& $this->query]); call_user_func_array($closure, [ & $this->query]);
} }
$result = $this->buildQuery()->relation($subRelation)->select(); $result = $this->buildQuery()->relation($subRelation)->select();
$this->hydratePivot($result); $this->hydratePivot($result);
@@ -303,7 +309,7 @@ class BelongsToMany extends Relation
$count = 0; $count = 0;
if (isset($result->$pk)) { if (isset($result->$pk)) {
$pk = $result->$pk; $pk = $result->$pk;
$count = $this->belongsToManyQuery($this->middle, $this->foreignKey, $this->localKey, ['pivot.' . $this->localKey => $pk])->count(); $count = $this->belongsToManyQuery($this->foreignKey, $this->localKey, ['pivot.' . $this->localKey => $pk])->count();
} }
return $count; return $count;
} }
@@ -316,7 +322,7 @@ class BelongsToMany extends Relation
*/ */
public function getRelationCountQuery($closure) public function getRelationCountQuery($closure)
{ {
return $this->belongsToManyQuery($this->middle, $this->foreignKey, $this->localKey, [ return $this->belongsToManyQuery($this->foreignKey, $this->localKey, [
'pivot.' . $this->localKey => [ 'pivot.' . $this->localKey => [
'exp', 'exp',
'=' . $this->parent->getTable() . '.' . $this->parent->getPk(), '=' . $this->parent->getTable() . '.' . $this->parent->getPk(),
@@ -335,7 +341,7 @@ class BelongsToMany extends Relation
protected function eagerlyManyToMany($where, $relation, $subRelation = '') protected function eagerlyManyToMany($where, $relation, $subRelation = '')
{ {
// 预载入关联查询 支持嵌套预载入 // 预载入关联查询 支持嵌套预载入
$list = $this->belongsToManyQuery($this->middle, $this->foreignKey, $this->localKey, $where)->with($subRelation)->select(); $list = $this->belongsToManyQuery($this->foreignKey, $this->localKey, $where)->with($subRelation)->select();
// 组装模型数据 // 组装模型数据
$data = []; $data = [];
@@ -359,13 +365,12 @@ class BelongsToMany extends Relation
/** /**
* BELONGS TO MANY 关联查询 * BELONGS TO MANY 关联查询
* @access public * @access public
* @param string $table 中间表名
* @param string $foreignKey 关联模型关联键 * @param string $foreignKey 关联模型关联键
* @param string $localKey 当前模型关联键 * @param string $localKey 当前模型关联键
* @param array $condition 关联查询条件 * @param array $condition 关联查询条件
* @return Query * @return Query
*/ */
protected function belongsToManyQuery($table, $foreignKey, $localKey, $condition = []) protected function belongsToManyQuery($foreignKey, $localKey, $condition = [])
{ {
// 关联查询封装 // 关联查询封装
$tableName = $this->query->getTable(); $tableName = $this->query->getTable();
@@ -374,6 +379,7 @@ class BelongsToMany extends Relation
->field(true, false, $table, 'pivot', 'pivot__'); ->field(true, false, $table, 'pivot', 'pivot__');
if (empty($this->baseQuery)) { if (empty($this->baseQuery)) {
$table = $this->pivot->getTable();
$query->join($table . ' pivot', 'pivot.' . $foreignKey . '=' . $tableName . '.' . $relationFk) $query->join($table . ' pivot', 'pivot.' . $foreignKey . '=' . $tableName . '.' . $relationFk)
->where($condition); ->where($condition);
} }
@@ -450,7 +456,7 @@ class BelongsToMany extends Relation
$ids = (array) $id; $ids = (array) $id;
foreach ($ids as $id) { foreach ($ids as $id) {
$pivot[$this->foreignKey] = $id; $pivot[$this->foreignKey] = $id;
$this->query->table($this->middle)->insert($pivot, true); $this->pivot->insert($pivot, true);
$result[] = $this->newPivot($pivot); $result[] = $this->newPivot($pivot);
} }
if (count($result) == 1) { if (count($result) == 1) {
@@ -488,8 +494,7 @@ class BelongsToMany extends Relation
if (isset($id)) { if (isset($id)) {
$pivot[$this->foreignKey] = is_array($id) ? ['in', $id] : $id; $pivot[$this->foreignKey] = is_array($id) ? ['in', $id] : $id;
} }
$this->query->table($this->middle)->where($pivot)->delete(); $this->pivot->where($pivot)->delete();
// 删除关联表数据 // 删除关联表数据
if (isset($id) && $relationDel) { if (isset($id) && $relationDel) {
$model = $this->model; $model = $this->model;
@@ -505,8 +510,9 @@ class BelongsToMany extends Relation
protected function baseQuery() protected function baseQuery()
{ {
if (empty($this->baseQuery)) { if (empty($this->baseQuery)) {
$pk = $this->parent->getPk(); $pk = $this->parent->getPk();
$this->query->join($this->middle . ' pivot', 'pivot.' . $this->foreignKey . '=' . $this->query->getTable() . '.' . $this->query->getPk())->where('pivot.' . $this->localKey, $this->parent->$pk); $table = $this->pivot->getTable();
$this->query->join($table . ' pivot', 'pivot.' . $this->foreignKey . '=' . $this->query->getTable() . '.' . $this->query->getPk())->where('pivot.' . $this->localKey, $this->parent->$pk);
$this->baseQuery = true; $this->baseQuery = true;
} }
} }