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 Controller
Friends
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?
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