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

Можно ли использовать пул демонов кэша памяти для более эффективного совместного использования сеансов?

Web

Отображение JSON с помощью PHP

Web

Как предотвратить SQL-инъекцию в PHP?

ТОП-100 паролей сети: лучшие из лучших, худшие из худших
Web

ТОП-100 паролей сети: лучшие из лучших, худшие из худших

×