试试这个:
// Tree.php
public function perchBird($birdId)
{
$perched = $this->birds->pluck('id')->toArray();
$perched = array_combine($perched, array_fill(0, count($perched), ['index' => DB::raw('`index`+1')]));
$perched[$birdId] = ['index' => 1];
$this->birds()->sync($perched);
}
分解:
1) 获取已栖息鸟类的 ID
$perched = $this->birds->pluck('id')->toArray();
2) 使用 DB::raw 创建一个关联数组,其中栖息鸟类的 id 作为键,更新语句作为值,以便 Laravel 理解它是 MySQL 计算,而不是本身的值。这样我们就可以获取现有的索引并增加它。
$perched = array_combine($perched, array_fill(0, count($perched), ['index' => DB::raw('`index`+1')]));
3) 将新栖息的鸟添加到数组中,索引为 1。
$perched[$birdId] = ['index' => 1];
4) 触发数据透视表同步
$this->birds()->sync($perched);
值得注意的是,sync 方法将单独运行每个更新语句,这可能会令人望而却步,具体取决于您期望拥有的栖息鸟类的数量或更新它们的频率。另一种方法是执行一个原始查询来增加索引,然后再执行一个查询来栖息一只新鸟:
public function perchBird($birdId)
{
DB::update('update bird_tree set `index` = (`index`+1) where tree_id = ?', [$this->id]);
$this->birds()->attach($birdId, ['index' => 1]);
}
按照要求,不完全是 Eloquent,但仍然非常简单易读。