首先,这种顺序是单向的。您不能将同一列用于游戏的关卡顺序,反之亦然。
现在,您可以通过覆盖关系上的attach 方法来实现所需的功能,以检查当前最大位置并相应地添加下一个以进行插入(不创建事件或其他任何内容,因为这与level 无关创建本身,而不是将其附加到游戏中)。
话虽如此,您需要扩展 Eloquent Model 或使用 trait 才能使用您的自定义 BelongsToMany 关系。像下面这样的东西应该可以完成这项工作(没有 cmets 等使其可能简洁)。
// Game model
class Game extends Eloquent {
use SortablePivotModelTrait;
public function levels()
{
return $this->sortableBelongsToMany('Level', 'order')->withPivot('order');
}
//...
}
// SortablePivotModelTrait.php
use Illuminate\Database\Eloquent\Model;
trait SortablePivotModelTrait {
public function sortableBelongsToMany($related, $orderColumn = null, $table = null, $foreignKey = null, $otherKey = null, $relation = null)
{
// all the code of belongsToMany method needs to go here
// ...
// then just:
return new SortableBelongsToMany($query, $this, $table, $foreignKey, $otherKey, $relation, $orderColumn);
}
}
// SortableBelongsToMany.php
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
class SortableBelongsToMany extends BelongsToMany {
protected $orderColumn;
public function __construct(Builder $query, Model $parent, $table, $foreignKey, $otherKey, $relationName = null, $orderColumn = 'order')
{
$this->orderColumn = $orderColumn;
parent::__construct($query, $parent, $table, $foreignKey, $otherKey, $relationName);
}
public function attach($id, array $attributes = array(), $touch = true)
{
$attributes = array_merge($attributes, [$this->getOrderColumnName() => $this->getNextPosition()]);
return parent::attach($id, $attributes, $touch);
}
public function getNextPosition()
{
return 1 + $this->newPivotQuery()->max($this->getOrderColumnName());
}
public function getOrderColumnName()
{
return $this->orderColumn;
}
}
这样你就可以做到:
$level = new Level;
// do some stuff with the created level
$game = Game::find($id);
// then
$game->save($level);
// or
$level->save();
$game->levels()->attach($level);