2015-08-23 16 views
9

Tôi đã này hoá đơn bảng mà trong đó có cơ cấu như sauLàm thế nào để xóa các bản ghi liên quan đến mềm khi xóa một bản ghi cha trong Laravel?

id | name | amount | deleted_at 
2 iMac 1500 | NULL 

và một bảng thanh toán với cơ cấu như sau

id | invoice_id | amount | deleted_at 
2 2   1000 | NULL 

Invoice Mẫu

class Invoice extends Model { 

    use SoftDeletes; 

} 

đây là đoạn code để xóa các hóa đơn

public function cance(Request $request,$id) 
{ 
    $record = Invoice::findOrFail($id); 
    $record->delete(); 
    return response()->json([ 
     'success' => 'OK', 
    ]); 
} 

Thanh toán mô hình

class Payment extends Model { 

    use SoftDeletes; 

} 

Các softDelete trên bảng Invoice hoạt động hoàn hảo nhưng hồ sơ liên quan của nó (thanh toán) vẫn exists.How nào để tôi xóa chúng bằng cách sử softDelete?

Trả lời

10

Eloquent không cung cấp xóa tự động các đối tượng liên quan, do đó bạn sẽ cần tự viết một số mã. May mắn thay, nó khá đơn giản.

Mô hình Eloquent các sự kiện khác nhau trong các giai đoạn khác nhau của vòng đời của chế độ - bạn có thể đọc thêm tại đây: http://laravel.com/docs/5.1/eloquent#events. Những gì bạn cần là một người nghe sẽ chạy khi xóa sự kiện được kích hoạt - người nghe này sau đó sẽ xóa tất cả các đối tượng liên quan.

Bạn có thể đăng ký người nghe mô hình theo phương thức khởi động() của mô hình. Trình nghe phải lặp qua tất cả các khoản thanh toán cho hóa đơn bị xóa và nên xóa từng khoản một. Xóa hàng loạt sẽ không hoạt động ở đây vì nó sẽ thực thi truy vấn SQL trực tiếp bỏ qua các sự kiện mô hình.

này sẽ làm các trick:

class MyModel extends Model { 
    protected static function boot() { 
    parent::boot(); 

    static::deleted(function ($invoice) { 
     $invoice->payments()->delete(); 
    }); 
    } 
} 
+0

Không hoạt động! FatalErrorException trong dòng Invoice.php 18: Không thể thực hiện phương pháp tĩnh Illuminate \ Database \ Eloquent \ Model :: boot() không tĩnh trong lớp App \ Models \ Invoice – user3407278

+0

Đã sửa lỗi, hàm bị thiếu công cụ sửa đổi tĩnh –

+0

Điều đó làm việc rất đẹp ! Cảm ơn rất nhiều! Điều này có gây ra bất kỳ vấn đề hiệu suất nào khi xóa mềm nói khoảng 100 bản ghi không? – user3407278

8

Bạn có thể thực hiện một trong 2 cách bằng cách này.

Cách đơn giản nhất sẽ được ghi đè phương pháp Eloquents delete() và bao gồm các mô hình liên quan cũng ví dụ:

public function delete() 
{ 
    $this->payments()->delete(); 
    return parent::delete(); 
} 

Các phương pháp trên sẽ làm việc chỉ cần tìm nhưng có vẻ như một chút bẩn và tôi muốn nói đó là không phải là phương pháp ưa thích trong cộng đồng.

Cách sạch hơn (IMO) sẽ được khai thác vào Eloquents sự kiện ví dụ .:

public static function boot() 
{ 
    parent::boot(); 

    static::deleting(function($invoice) { 
     $invoice->payments()->delete(); 

    }); 
} 

Hoặc (nhưng không phải cả hai) của các phương pháp trên sẽ đi trong mô hình Invoice của bạn. Ngoài ra, tôi giả định rằng bạn đã thiết lập mối quan hệ trong mô hình của mình, tuy nhiên, tôi không chắc liệu bạn có cho phép nhiều khoản thanh toán cho một hóa đơn hay không. Dù bằng cách nào bạn cũng có thể cần phải thay đổi payments() trong các ví dụ cho bất kỳ điều gì bạn đã đặt tên cho mối quan hệ trong mô hình hóa đơn của mình.

Hy vọng điều này sẽ hữu ích!

+0

Calling xóa() trên mối quan hệ thanh toán trực tiếp sẽ bỏ qua các mô hình và sẽ không kích hoạt SoftDelete trên các mô hình liên quan. Chúng sẽ bị xóa khỏi cơ sở dữ liệu. Để làm cho mềm bị xóa, bạn cần phải gọi delete() trên mỗi mô hình liên quan. –

+0

Bạn cũng thiếu câu lệnh trả về trong phương thức xóa đã ghi đè của mình - nó phải làm "return parent :: delete();", nếu không bạn sẽ mất giá trị sẽ được trả về từ delete() nếu bạn không ghi đè nó. –

+0

@ jedrzej.kurylo, tôi vừa thử nghiệm để chắc chắn và CÓ bạn có thể sử dụng xóa mềm trên một mối quan hệ! –

Các vấn đề liên quan