[php] Laravel (Eloquent ORM)에서 관련 행 자동 삭제

이 구문을 사용하여 행을 삭제할 때 :

$user->delete();

예를 들어 자동으로 수행 할 수 있도록 일종의 콜백을 첨부하는 방법이 있습니까?

$this->photo()->delete();

가급적 모델 클래스 내부.



답변

이것이 Eloquent 이벤트 ( http://laravel.com/docs/eloquent#model-events )에 대한 완벽한 사용 사례라고 생각합니다 . “삭제”이벤트를 사용하여 정리를 수행 할 수 있습니다.

class User extends Eloquent
{
    public function photos()
    {
        return $this->has_many('Photo');
    }

    // this is a recommended way to declare event handlers
    public static function boot() {
        parent::boot();

        static::deleting(function($user) { // before delete() method call this
             $user->photos()->delete();
             // do the rest of the cleanup...
        });
    }
}

참조 무결성을 보장하기 위해 모든 것을 트랜잭션 안에 넣어야합니다.


답변

마이그레이션에서 실제로 설정할 수 있습니다.

$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');

출처 : http://laravel.com/docs/5.1/migrations#foreign-key-constraints

제약 조건의 “삭제시”및 “업데이트시”속성에 대해 원하는 작업을 지정할 수도 있습니다.

$table->foreign('user_id')
      ->references('id')->on('users')
      ->onDelete('cascade');


답변

참고 :이 답변은 Laravel 3 용으로 작성되었습니다 . 따라서 최신 버전의 Laravel에서 잘 작동하거나 작동하지 않을 수 있습니다.

실제로 사용자를 삭제하기 전에 관련된 모든 사진을 삭제할 수 있습니다.

<?php

class User extends Eloquent
{

    public function photos()
    {
        return $this->has_many('Photo');
    }

    public function delete()
    {
        // delete all related photos 
        $this->photos()->delete();
        // as suggested by Dirk in comment,
        // it's an uglier alternative, but faster
        // Photo::where("user_id", $this->id)->delete()

        // delete the user
        return parent::delete();
    }
}

도움이 되었기를 바랍니다.


답변

사용자 모델에서의 관계 :

public function photos()
{
    return $this->hasMany('Photo');
}

기록 및 관련 삭제 :

$user = User::find($id);

// delete related   
$user->photos()->delete();

$user->delete();


답변

이 문제를 해결하는 방법에는 세 가지가 있습니다.

1. 모델 부팅시 Eloquent 이벤트 사용 (참조 : https://laravel.com/docs/5.7/eloquent#events )

class User extends Eloquent
{
    public static function boot() {
        parent::boot();

        static::deleting(function($user) {
             $user->photos()->delete();
        });
    }
}

2. Eloquent 이벤트 옵저버 사용하기 (ref : https://laravel.com/docs/5.7/eloquent#observers )

AppServiceProvider에서 다음과 같이 관찰자를 등록합니다.

public function boot()
{
    User::observe(UserObserver::class);
}

다음으로 다음과 같이 Observer 클래스를 추가합니다.

class UserObserver
{
    public function deleting(User $user)
    {
         $user->photos()->delete();
    }
}

3. 외래 키 제약 사용 (참조 : https://laravel.com/docs/5.7/migrations#foreign-key-constraints )

$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');


답변

Laravel 5.2부터 문서에는 이러한 종류의 이벤트 핸들러가 AppServiceProvider에 등록되어야한다고 명시되어 있습니다.

<?php
class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        User::deleting(function ($user) {
            $user->photos()->delete();
        });
    }

더 나은 애플리케이션 구조를 위해 클로저 대신 별도의 클래스로 이동한다고 가정합니다.


답변

이에 대한 delete방법을 재정의하는 것이 좋습니다 . 이렇게하면 delete메서드 자체에 DB 트랜잭션을 통합 할 수 있습니다 . 이벤트 방식을 사용하는 경우 delete호출 할 때마다 DB 트랜잭션 으로 메서드 호출을 가려야합니다 .

당신의에서 User모델.

public function delete()
{
    \DB::beginTransaction();

     $this
        ->photo()
        ->delete()
    ;

    $result = parent::delete();

    \DB::commit();

    return $result;
}