2016-12-03 66 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 –