Laravel -集合::删除方法不存在

nimxete2  于 2022-04-21  发布在  其他
关注(0)|答案(6)|浏览(156)

我正在尝试测试 Boot ()static::deleting方法,当通过Eloquent删除模型时,该方法应该会触发。
tinker App\User::find(6)->delete();中的命令返回“方法[...]集合::删除不存在”。
如果我尝试使用App\User::where('id', 6)->delete();,那么static::deleting方法不会被触发,因为Eloquent没有加载。如果我使用->first()加载Eloquent,那么我会得到相同的错误,声明方法不存在。
下面是整个用户模型

<?php

namespace App;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{
    use Notifiable;

    public function profile() {
        return $this->hasOne(Profile::class);
    }

    public function posts() {
        return $this->hasMany(Post::class);
    }

    public function tempUploads() {
        return $this->hasMany(TempUploads::class);
    }
    
    protected static function boot() {
        parent::boot();
        
        static::created(function ($user) {
            $user->profile()->create(['id' => $user->username, 'avatar' => '/storage/avatars/edit-profile.png']);
            mkdir(public_path() . "/storage/images/" . $user->username , 0755);

            // $data = [
            //  'user_id' => $user->username
            // ];
            // Mail::to($user->email)->send(new WelcomeMail($data));
        });

        static::deleting(function ($user) {
            $user->posts->delete();
            if ($user->profile->avatar != '/storage/avatars/edit-profile.png') {
                if ($user->profile->cover != NULL && $user->profile->cover != '') {
                    $oldAvatar = $_SERVER['DOCUMENT_ROOT'] . $user->profile->avatar;
                    $oldCover = $_SERVER['DOCUMENT_ROOT'] . $user->profile->cover;
                    if (is_file($oldAvatar) && is_file($oldCover)) {
                        unlink($oldAvatar);
                        unlink($oldCover);
                    } else {
                        die("Грешка при изтриване на стария файл. File does not exist in profile deleting method.");
                    }
                }
            }
            $user->profile->delete();
        });
    }

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'username', 'email', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];
}

我已经花了几个小时在谷歌上寻找可能的解决方案,但还没有。
在触发 Boot 删除方法时,我应该如何正确地删除用户模型?

bnl4lu3b

bnl4lu3b1#

在您的deleting侦听器中,您正在尝试删除其他内容,这是导致错误的集合。
$user->posts是与Posts的关系,该关系是复数,是hasMany关系(最有可能),因此它返回一个集合always。集合没有delete方法。您必须循环访问该集合,并对每个Post调用delete

// calling `delete()` on a Collection not a Model
// will throw the error you see
$user->posts->delete();

// iterate through the Collection
foreach ($user->posts as $post) {
    $post->delete();
}

附注:您不能对模型和查询执行任何批量操作,也不能触发事件。所有模型事件都基于模型的单个例程。直接查询将绕过模型。

cl25kdpy

cl25kdpy2#

你可以优化lagbox's answer,只使用一个查询就可以删除所有的帖子,在这个例子中,他对每个附加到用户的帖子执行一个delete查询。
对于单个delete查询,可以直接使用关系的查询生成器:

$user->posts()->delete();

或者使用集合的pluck方法和单独的查询:

Post::where('id', $user->posts->pluck('id'))->delete();
vulvrdjw

vulvrdjw3#

您也可以使用高阶消息:

$user->posts->each->delete();
myss37ts

myss37ts5#

我在我的控制器文件中使用这个来删除数据库条目:

public function destroy(Item $id) {
        $id->destroy($id->id);
        //return view('inv.delete', compact('id'));
        return redirect('/inv');
    }
jv4diomz

jv4diomz6#

$user->posts()->delete()   will work

$user->posts->delete()   will not work

**因为 * $user-〉posts()是一个查询,而不是集合

相关问题