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

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->table = $table;
if (is_null($this->name)) {
$this->name = $table;
}
}
}

View File

@@ -24,8 +24,9 @@ class BelongsToMany extends Relation
{
// 中间表表名
protected $middle;
// 中间表模型
// 中间表模型名称
protected $pivotName;
// 中间表模型对象
protected $pivot;
/**
@@ -43,8 +44,13 @@ class BelongsToMany extends Relation
$this->model = $model;
$this->foreignKey = $foreignKey;
$this->localKey = $localKey;
$this->middle = $table;
$this->query = (new $model)->db();
if (false === strpos($table, '\\')) {
$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)
{
$this->pivot = $pivot;
$this->pivotName = $pivot;
return $this;
}
@@ -63,9 +69,9 @@ class BelongsToMany extends Relation
* @param $data
* @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);
}
@@ -102,7 +108,7 @@ class BelongsToMany extends Relation
// 关联查询
$pk = $this->parent->getPk();
$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)
{
if ($closure) {
call_user_func_array($closure, [& $this->query]);
call_user_func_array($closure, [ & $this->query]);
}
$result = $this->buildQuery()->relation($subRelation)->select();
$this->hydratePivot($result);
@@ -303,7 +309,7 @@ class BelongsToMany extends Relation
$count = 0;
if (isset($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;
}
@@ -316,7 +322,7 @@ class BelongsToMany extends Relation
*/
public function getRelationCountQuery($closure)
{
return $this->belongsToManyQuery($this->middle, $this->foreignKey, $this->localKey, [
return $this->belongsToManyQuery($this->foreignKey, $this->localKey, [
'pivot.' . $this->localKey => [
'exp',
'=' . $this->parent->getTable() . '.' . $this->parent->getPk(),
@@ -335,7 +341,7 @@ class BelongsToMany extends Relation
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 = [];
@@ -359,13 +365,12 @@ class BelongsToMany extends Relation
/**
* BELONGS TO MANY 关联查询
* @access public
* @param string $table 中间表名
* @param string $foreignKey 关联模型关联键
* @param string $localKey 当前模型关联键
* @param array $condition 关联查询条件
* @return Query
*/
protected function belongsToManyQuery($table, $foreignKey, $localKey, $condition = [])
protected function belongsToManyQuery($foreignKey, $localKey, $condition = [])
{
// 关联查询封装
$tableName = $this->query->getTable();
@@ -374,6 +379,7 @@ class BelongsToMany extends Relation
->field(true, false, $table, 'pivot', 'pivot__');
if (empty($this->baseQuery)) {
$table = $this->pivot->getTable();
$query->join($table . ' pivot', 'pivot.' . $foreignKey . '=' . $tableName . '.' . $relationFk)
->where($condition);
}
@@ -450,7 +456,7 @@ class BelongsToMany extends Relation
$ids = (array) $id;
foreach ($ids as $id) {
$pivot[$this->foreignKey] = $id;
$this->query->table($this->middle)->insert($pivot, true);
$this->pivot->insert($pivot, true);
$result[] = $this->newPivot($pivot);
}
if (count($result) == 1) {
@@ -488,8 +494,7 @@ class BelongsToMany extends Relation
if (isset($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) {
$model = $this->model;
@@ -505,8 +510,9 @@ class BelongsToMany extends Relation
protected function baseQuery()
{
if (empty($this->baseQuery)) {
$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);
$pk = $this->parent->getPk();
$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;
}
}