2017-03-11 1 views
1

Ich Verlängerung der rainlab.user Plugin jeder Benutzer zu ermöglichen, Freunde über eine einfache Zwischentabelle mit den folgenden Bereichen zu haben:OctoberCMS: Wie man eine beidseitige Freundschaftsbeziehung beibehält?

user_id 
friend_id 
status 

ich das User Modell erweitert haben:

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); 
    }); 
}); 

Und auch erweitert die Rainlab.User ControllerFriends Register haben, wo alle Freunde eines Nutzers aufgelistet und können hinzugefügt und entfernt werden:

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', 
     ] 
    ]); 
}); 

Jetzt muss ich eine Zwei-Wege-Freundschaft pflegen. Wenn immer user_id und friend_id zu der friends Tabelle hinzugefügt wird, möchte ich automatisch friend_id und user_id zu der Tabelle hinzufügen. Um dies zu erreichen, umgesetzt ich afterSave und beforeSave im FriendsPivot Modell:

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); 
     } 
    } 
} 

Das Problem ist, dass beforeDelete nie aufgerufen. afterSave wird aufgerufen, aber beforeDelete wird nie aufgerufen und daher wird die Umkehrung der Beziehung nicht gelöscht (user_id - friend_id wird aus der Datenbank entfernt, aber friend_id - user_id wird nicht gelöscht). Warum wird beforeDelete nicht aufgerufen? Gibt es irgendetwas, was ich falsch mache? Gibt es einen besseren Weg, eine beidseitige Freundschaftsbeziehung aufrechtzuerhalten?

Antwort

0

Das klingt zunächst sehr seltsam, aber vielleicht liegt das an dem speziellen delete behavior des Pivot-Modells. Es scheint, dass es eine rohe Abfrage erstellt, die den QueryBuilder verwendet und damit alle regulären Eloquent-Ereignisse (Oktober) umgeht. In meinen Augen wäre die beste Lösung, das Lösch-Ereignis manuell in der Lösch-Methode auszulösen, aber ich bin unsicher, ob dies irgendwelche Nebenwirkungen hat. Vielleicht könnten Sie das testen und einen PR auf Github vorbereiten, wenn es funktioniert.

+0

Ich legte einen Haltepunkt auf dieser Linie: https://github.com/octobercms/library/blob/master/src/Database/Pivot.php#L88 und erkennen, dass, wenn ich einen Freund entfernen, Die 'delete' Methode der' October \ Rain \ Database \ Pivot' Klasse wird nicht aufgerufen. – Meysam

1

Ich habe diesen Beitrag gefunden, weil ich genau das gleiche versuche wie Sie. Wenn Sie das gelöst haben, frage ich mich, ob Sie bereit wären, Ihre Lösung zu teilen?

+0

Ich habe ein Problem für diese https://github.com/Octobercms/October/issues/2747 geöffnet und versuche, den Code zu debuggen. Ich werde Sie auf dem Laufenden halten, wenn etwas Neues passiert. – Meysam

+0

Es ist jetzt ein bestätigter Fehler und wird hoffentlich bald behoben https://github.com/Octobercms/October/issues/2747#issuecomment-297931317 – Meysam

Verwandte Themen