2016-12-03 63 views
1

对于参数的缘故,虽然该关系one2many(一个树具有鸟类)允许检查假想many2many例子来描述该问题。更新枢列的值

我有一个数据透视表,代表鸟类栖息在一棵树上 ,每只鸟的索引代表树上的鸟类顺序,这意味着独特的三重奏$table->unique(array('index', 'tree_id', 'bird_id'))

tree_id | bird_id | index 
-------- --------- ------- 
    ...  ...  ... 
    1   3  1 
    ...  ...  ... 

所以,当在树上一个新的鸟儿落地了,我希望它成为树的第一只小鸟,并增加在树上休息的指标。

什么这样做,有效地利用雄辩的方式吗?

回答

2

根据我的理解,你有许多树木和鸟模型之间的许多的关系,所以你的表应该是这样的:

- trees 
    - id 
    - name 
    ... 

- birds 
    - id 
    - name 
    - ... 

- bird_tree 
    - id 
    - bird_id 
    - tree_id 
    - index 

而且你的模型应该是这样的:

class Tree extends Model 
{ 

    public function birds() 
    { 
     return $this->belongsToMany(Bird::class) 
        ->withPivot('index') 
        ->withTimestamps(); 
    } 

} 

class Bird extends Model 
{ 

    public function trees() 
    { 
     return $this->belongsToMany(Tree::class) 
        ->withPivot('index') 
        ->withTimestamps(); 
    } 

} 

而如果你想添加一个新进入的数据透视表bird_tree,您可以使用attach()方法是这样的:

$tree->birds()->attach(1, ['index' => 1]); 
        ^
    bird's id_________| 

,如果你想,如果你想更新的bird_tree表中的任何条目的任何指标,你可以使用这个updateExistingPivot()方法来更新任何行,强制例如:

$tree->birds()->sync([$bird->id => [ 'index' => 'someValue'] ]); 

见Laravel文档为:

希望这有助于!

+0

10x抱歉关于延迟我会尽快在我测试解决方案时批准答案+1 –

2

这给一试:

// 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)获取已经栖息鸟类的IDS

$perched = $this->birds->pluck('id')->toArray(); 

2)创建栖息鸟类的关联数组IDS作为键和更新语句作为值,使用DB::raw,以便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]); 
} 

不完全是口若悬河,按照要求,但仍然相当简单和可读性。

+0

10x对于延迟抱歉,只要我测试解决方案,我会立即批准答案+1 –