Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/laravel/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
对同一关系使用contains方法后,Laravel belongsToMany attach()方法不起作用_Laravel_Many To Many - Fatal编程技术网

对同一关系使用contains方法后,Laravel belongsToMany attach()方法不起作用

对同一关系使用contains方法后,Laravel belongsToMany attach()方法不起作用,laravel,many-to-many,Laravel,Many To Many,我正在我的项目中进行友谊实现,但除了只添加朋友外,我希望像facebook一样拥有邀请功能,我使用多对多自引用方法 数据透视表架构: Schema::create('user_friends', function (Blueprint $table) { $table->primary(['user_id', 'friend_id']); $table->unsignedInteger('user_id'); $table-&g

我正在我的项目中进行友谊实现,但除了只添加朋友外,我希望像facebook一样拥有邀请功能,我使用多对多自引用方法

数据透视表架构:

    Schema::create('user_friends', function (Blueprint $table) {
        $table->primary(['user_id', 'friend_id']);
        $table->unsignedInteger('user_id');
        $table->unsignedInteger('friend_id');
        $table->timestamps();
        $table->timestamp('accepted_at')->nullable()->default(null);
        $table->timestamp('refused_at')->nullable()->default(null);

        $table->foreign('user_id')
        ->references('id')->on('users')
        ->onDelete('cascade');
        $table->foreign('friend_id')
        ->references('id')->on('users')
        ->onDelete('cascade');
    });
我将朋友/成为朋友分为3组:

  • 已确认的朋友,此类别包括我邀请的朋友和邀请我的朋友
  • 被邀请人:我邀请但未批准的人
  • 邀请者:那些邀请我但我还没答应的人
  • 以下是它们对应的代码:

    第一组:朋友:

        class User {
    
        //
    
        /**
         * Friendships that started by the user
         */
        public function friendsOfMine()
        {
            return $this->belongsToMany('App\User', 'user_friends', 'user_id', 'friend_id')
                        ->withPivot(['accepted_at', 'refused_at'])
                        ->wherePivot('accepted_at', '<>', null)
                        ->withTimestamps();
        }
    
        /**
         * Friendships that started by others
         */
        public function friendOfOthers()
        {
            return $this->belongsToMany('App\User', 'user_friends', 'friend_id', 'user_id')
                        ->withPivot(['accepted_at', 'refused_at'])
                        ->wherePivot('accepted_at', '<>', null)
                        ->withTimestamps();
        }
    
        // accessor allowing you call $user->friends
        public function getFriendsAttribute()
        {
            if (!array_key_exists('friends', $this->relations)) {
                $this->loadFriends();
            }
    
            return $this->getRelation('friends');
        }
    
        protected function loadFriends()
        {
            if (!array_key_exists('friends', $this->relations)) {
                $friends = $this->mergeFriends();
    
                $this->setRelation('friends', $friends);
            }
        }
    
        protected function mergeFriends()
        {
            return $this->friendsOfMine->merge($this->friendOfOthers);
        }
    
    第3组:邀请者:

    /**
     * Users that invite this user as friend.
     */
    public function invitors()
    {
        return $this->belongsToMany('App\User', 'user_friends', 'friend_id', 'user_id')
                    ->withPivot(['accepted_at', 'refused_at'])
                    ->wherePivot('accepted_at', null)
                    ->withTimestamps();
    }
    
    然后,当我想邀请一个新用户时,我想确保这个新用户不属于以下3个组:

    public function inviteFriend(User $user)
    {
    
        if (!$this->is($user) &&
            !$this->friends->contains($user) &&
            !$this->invitees->contains($user) &&
            !$this->invitors->contains($user)) {
    
            $this->invitees()->attach($user);  
        }
    }
    
    然后出现了一个奇怪的问题,我使用dd()来检查进度,并确认条件是正确的和正确的

    $this->invitees()->attach($user);
    
    已执行,但未正确添加$user, 但是,如果我删除这一个条件检查(不是另一个)

    并且函数变得

    public function inviteFriend(User $user)
    {
    
        if (!$this->is($user) &&
            !$this->friends->contains($user) &&
            // !$this->invitees->contains($user) &&
            !$this->invitors->contains($user)) {
    
            $this->invitees()->attach($user);  
        }
    }
    
    然后它将正常工作,但是,随后可能会重复邀请同一个人,然后导致SQL约束冲突


    有人能帮我解决这个问题吗?提前谢谢你

    您可以使用syncWithoutDetaching而不是attach功能:

    public function inviteFriend(User $user)
    {
    
      if (!$this->is($user) &&
        !$this->friends->contains($user) &&
        !$this->invitors->contains($user)) {
    
        $this->invitees()->syncWithoutDetaching([$user->id]);  
      }
    }
    

    这个函数如果不存在就附加用户id

    经过更多的搜索,我终于找到了一个解决问题的方法,我认为这种方法在效率方面可能比我原来的方法要好,因为对于这种情况,
    collection->contains()

        if (!$this->is($user) &&
            !$this->friendsOfMine()->wherePivot('friend_id', $user->id)->exists() &&
            !$this->friendOfOthers()->wherePivot('user_id', $user->id)->exists() &&
            !$this->invitees()->wherePivot('friend_id', $user->id)->exists() &&
            !$this->invitors()->wherePivot('user_id', $user->id)->exists()) {
            $this->invitees()->attach($user);
       }
    

    谢谢你的回复,我尝试了你的建议,但是得到的结果和我原来的代码一样。
    public function inviteFriend(User $user)
    {
    
      if (!$this->is($user) &&
        !$this->friends->contains($user) &&
        !$this->invitors->contains($user)) {
    
        $this->invitees()->syncWithoutDetaching([$user->id]);  
      }
    }
    
        if (!$this->is($user) &&
            !$this->friendsOfMine()->wherePivot('friend_id', $user->id)->exists() &&
            !$this->friendOfOthers()->wherePivot('user_id', $user->id)->exists() &&
            !$this->invitees()->wherePivot('friend_id', $user->id)->exists() &&
            !$this->invitors()->wherePivot('user_id', $user->id)->exists()) {
            $this->invitees()->attach($user);
       }