【问题标题】:OctoberCMS: How to maintain a two-way friendship relation?十月CMS:如何维持双向的友谊关系?
【发布时间】:2017-08-02 02:16:02
【问题描述】:

我正在扩展rainlab.user 插件,以允许每个用户通过具有以下字段的简单中间表来拥有朋友:

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?有什么我做错了吗?有没有更好的方法来维持双向的友谊关系?

【问题讨论】:

    标签: mysql laravel octobercms octobercms-plugins


    【解决方案1】:

    我发现这篇文章是因为我想做和你一样的事情。如果您已经解决了这个问题,那么我想知道您是否愿意分享您的解决方案?

    【讨论】:

    【解决方案2】:

    一开始这听起来很奇怪,但也许这是因为 Pivot 模型的特殊delete behavior。它似乎使用 QueryBuilder 构建了一个原始查询,因此绕过了任何常规的 Eloquent(10 月)事件。 在我看来,最好的解决方案是在 delete 方法中手动触发 delete 事件,但我不确定这是否有任何副作用。 如果可行的话,也许你可以测试一下,并在 Github 上准备一个 PR。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-31
    • 2017-06-02
    • 2012-10-28
    • 1970-01-01
    • 1970-01-01
    • 2023-04-04
    相关资源
    最近更新 更多