Web

Почему Laravel удаляет данные связанной модели по user_id в загруженной функции модели User

Я прочитал часть документации Laravel по событиям и закрытиям для моделей. В моем проекте есть различные модели, в которых пользователь может иметь данные, связанные с ними в нескольких таблицах по столбцу user_id. 

Столбец user_id, который есть у меня в таблицах, структурирован как целое беззнаковое число (я знаю, что я мог бы использовать столбец foreignId, так как это своего рода унаследованный подход).

Код выглядит как:

$table->integer('user_id')->unsigned()->nullable()->index();

 Я хотел бы удалить пользовательские данные по их идентификатору в этих таблицах, и вместо того, чтобы создавать функцию удаления и захватывать каждую модель, для которой я хочу удалить данные, я использовал функцию booted для завершения. Таким образом, я создаю событие для прослушивания и удаляю связанные данные модели. Но при попытке удалить мою учетную запись возникает ошибка, так как другие данные в других таблицах не удаляются, и я получаю следующую ошибку:

Вызов неопределенного метода App\Models\User::relationship()

 

Моя пользовательская модель выглядит так:

<?php

 

namespace App\Models;

 

use Illuminate\Contracts\Auth\MustVerifyEmail;

use Illuminate\Foundation\Auth\User as Authenticatable;

use Illuminate\Notifications\Notifiable;

use Illuminate\Database\Eloquent\SoftDeletes;

use Illuminate\Database\Eloquent\Model;

 

use Tymon\JWTAuth\Contracts\JWTSubject;

 

class User extends Authenticatable implements JWTSubject, MustVerifyEmail {

    use Notifiable, SoftDeletes;

 

    // Атрибуты для множественного присваивания

    protected $fillable = [

        'Имя', 'Фамилия', 'почта', 'пароль'

    ];

 

    // Атрибуты для скрытых полей массива

    protected $hidden = [

        'пароль', 'токен участника'

    ];

 

    // Атрибуты для нативных типов

    protected $casts = [

        'email_verified_at' => 'datetime'

    ];

 

    // Получение идентификатора субъекта JWT.

    public function getJWTIdentifier() {

      return $this->getKey();

    }

 

    // Возврат значения массива, содержащий любые пользовательские утверждения, которые должны быть добавлены к JWT

    public function getJWTCustomClaims() {

      return [];

    }

 

    // Маршрутизация уведомлений для канала Slack.

    public function routeNotificationForSlack($notification) {

        $url = $this->slack_webhook;

        $webhook = (isset($url) && !empty($url)) ? $url : null;

        return $webhook;

    }

 

    // «booted» метод для модели

    protected static function booted() {

        static::deleted(function ($model) {

            $model->relationship()->delete();

        });

    }

}

 

И пример (множественных) моделей, которые у меня есть для UptimeChecks.

Код выглядит так:

<?php

 

namespace App\Models;

 

use Illuminate\Database\Eloquent\Model;

 

class UptimeChecks extends Model {

 

    // Таблица связей с моделью

    protected $table = 'uptime_checks';

 

    // Связь пользователя с таблицей

    public function user() {

      return $this->belongsTo('App\User');

    }

}

 

Затем это все запускается функцией deleteAccount в моем API, которая удаляет учетную запись пользователя, но не удаляет данные в других таблицах. Что мне не хватает и как я могу проверить, удалены ли другие данные, прежде чем подтвердить пользователю, что его учетная запись и связанные данные исчезли?

// Удаление аккаунта

public function deleteAccount(Request $request) {

 

    // попытка удаления аккаунта

    try {

        $user = User::findOrFail(Auth::id());

        $user->delete();

        // операция завершилась успешно!

        return response()->json(['success' => true, 'message' => 'Твой аккаунт был удален'], 200);

    } catch (Exception $e) {

        // ошибка

        return response()->json(['success' => false, 'message' => 'Не удалось удалить аккаунт'], 422);

    }

}

 

Ответ 1

В Laravel при выполнении $model->relationship()->delete(); вам потребуется определить отношения, а relationship() выглядит как копипаст кода. Просто добавьте отношения к вашей модели User.

class User extends Authenticatable implements JWTSubject, MustVerifyEmail {

    ...

    public function uptimeChecks() {

        return $this->hasMany(UptimeChecks::class);

    }

}

 

Теперь вы можете получить к ней доступ и удалить отношения в вашем методе загрузки.

$model->uptimeChecks()->delete();

 

Ответ 2

Вам нужно создать функцию в User.php

public function uptimeCheck() {

   return $this->hasOne('App\UptimeChecks');

}

 

и изменить функцию загрузки

$model-> uptimeCheck () -> delete ();

 

Такие же действия нужно проделать для всех родственных отношений.

 

Ответ 3

Вероятно, вместо этого должно быть: $model->user()->delete(). Больше ничего делать не надо.

Если же это не должно быть сделано так, просто пересмотрите направление связи. 

Схожие статьи

Web

Как выполнить усечение строки до первых n символов и добавить три точки в конце

Web

Как извлечь данные из файла csv в PHP

Web

Когда использовать self вместо $this?

Web

Принудительная загрузка файла с помощью PHP