2017-03-11 60 views
1

我延長rainlab.user插件,允許每個用戶通過一個簡單的中間表具有以下字段的朋友:OctoberCMS:如何保持雙向友誼關係?

user_id 
friend_id 
status 

我已經延長了User型號:

use RainLab\User\Models\User as FrontUser; 

FrontUser::extend(function($model) { 

    $model->belongsToMany['friends']=[ 
     'RainLab\User\Models\User', 
     'table' => 'meysam_social_friends', 
     'pivot' => ['status'], 
     'pivotModel' => 'Meysam\Social\Models\FriendsPivot', 
     'timestamps' => true, 
     'key'  => 'user_id', 
     'otherKey' => 'friend_id' 
    ]; 

    $model->addDynamicMethod('isFriendWith', function (FrontUser $user) use ($model) { 
     $model->friends->contains($user->id); 
    }); 

    $model->addDynamicMethod('addFriend', function (FrontUser $user) use ($model) { 
     $model->friends()->attach($user->id); 
    }); 

    $model->addDynamicMethod('removeFriend', function (FrontUser $user) use ($model) { 
     $model->friends()->detach($user->id); 
    }); 
}); 

而且還將Rainlab.User Controller擴展爲具有Friends選項卡,其中列出用戶的所有朋友並且可以添加和刪除:

use RainLab\User\Controllers\Users as UsersController; 

UsersController::extend(function($controller) { 

    if(!isset($controller->implement['Backend.Behaviors.RelationController'])) { 
     $controller->implement[] = 'Backend.Behaviors.RelationController'; 
    } 
    $controller->relationConfig = '$/meysam/social/controllers/user/config_relations.yaml'; 
}); 

UsersController::extendFormFields(function($form, $model, $context) { 
    if(!$model instanceof FrontUser or $context != 'preview'){ 
     // friends tab should not be displayed in update and create contexts 
     return; 
    } 

    $form->addTabFields([ 
     'friends' => [ 
      'label' => '', 
      'tab' => 'Friends', 
      'type' => 'partial', 
      'path' => '$/meysam/social/controllers/user/_friends.htm', 
     ] 
    ]); 
}); 

現在我需要保持雙向的友誼關係。即無論何時將user_idfriend_id添加到friends表中,我想自動將friend_iduser_id也添加到表中。要做到這一點,我在FriendsPivot模型來實現afterSavebeforeSave

class FriendsPivot extends Pivot 
{ 
    /* 
    * Validation 
    */ 
    public $rules = [ 
     'status' => 'required' 
    ]; 

    public $belongsTo = [ 
     'user' => ['RainLab\User\Models\User', 'key' => 'user_id'], 
     'friend' => ['RainLab\User\Models\User', 'key' => 'friend_id'] 
    ]; 

    public function getStatusOptions() 
    { 
     return [ 
      1 => 'Pending', 
      2 => 'Approved', 
      3 => 'Blocked', 
     ]; 
    } 

    public function afterSave() 
    { 
     Log::info('Saving pivot...'); 

     if(!$this->friend->isFriendWith($this->user)) { 
      $this->friend->addFriend($this->user); 
     } 
    } 

    public function beforeDelete() 
    { 
     Log::info('Deleting pivot...'); 

     if($this->friend->isFriendWith($this->user)) { 
      $this->friend->removeFriend($this->user); 
     } 
    } 
} 

的問題是,beforeDelete不會被調用。 afterSave被調用,但beforeDelete永遠不會被調用,因此關係的反轉不會被刪除(user_id - friend_id被從數據庫中刪除,但friend_id-user_id不會被刪除)。爲什麼beforeDelete不叫?有什麼我做錯了嗎?有沒有更好的方法來維持雙向的友誼關係?

回答

0

這聽起來很奇怪,但也許這是因爲Pivot模型的特殊delete behavior。它似乎使用QueryBuilder構建了一個原始查詢,因此繞過了任何常規的Eloquent(十月)事件。 在我看來,最好的解決方案是在刪除方法中手動觸發刪除事件,但我不確定這是否有任何副作用。 也許你可以測試一下,並準備在Github上的公關如果它的作品。

+0

我把一個破發點上這一行: https://github.com/octobercms/library/blob/master/src/Database/Pivot.php#L88 並意識到如果我刪除了一個朋友說,不會調用'October \ Rain \ Database \ Pivot'類的'delete'方法。 – Meysam

1

我發現這篇文章,因爲我試圖做和你一樣的事情。如果你已經解決了這個問題,那麼我想知道你是否願意分享你的解決方案?

+0

我爲此https://github.com/octobercms/october/issues/2747打開了一個問題,並試圖調試代碼。如果發生任何新情況,我會盡快發佈。 – Meysam

+0

這是一個已確認的錯誤,並希望很快將被修復https://github.com/octobercms/october/issues/2747#issuecomment-297931317 – Meysam