مقاله

SoftDeletes trait، deleted_at، restore، withTrashed و trash در پنل ادمین — حذف امن بدون از دست دادن داده.

Soft Delete در Laravel — حذف نرم، بازیابی و forceDelete

Soft Delete در Laravel — حذف نرم، بازیابی و forceDelete

«پست را حذف کن» در CMS یعنی معمولاً «از سایت پنهان کن، نه از دیتابیس پاک کن». Soft Delete با ستون deleted_at همین را می‌دهد — audit trail، بازیابی اشتباه کاربر، و compliance. در این پورتفولیو Post، Category و Tag همه SoftDeletes دارند.

فعال‌سازی

use Illuminate\Database\Eloquent\SoftDeletes;

class Post extends Model
{
    use SoftDeletes;
}
$table->softDeletes(); // migration

رفتار پیش‌فرض

Post::all() و query عادی رکوردهای حذف‌شده را نمی‌بینند — global scope خودکار.

حذف و بازیابی

$post->delete();        // soft
$post->restore();       // بازیابی
$post->forceDelete();   // حذف واقعی از DB

Query با trashed

Post::withTrashed()->find($id);
Post::onlyTrashed()->paginate(20);
Post::withTrashed()->where('slug', $slug)->first();

رابطه و soft delete

اگر parent soft delete شود، children چه؟ خودتان cascade منطقی تعریف کنید — Laravel خودکار cascade نمی‌دهد مگر در migration foreign key.

// در Observer deleting
$post->comments()->delete(); // soft هر کدام SoftDeletes داشته باشد

unique با soft delete

slug unique بعد از soft delete conflict می‌دهد — راه‌حل: unique composite با deleted_at یا append timestamp به slug هنگام delete.

Filament / admin trash

لیست onlyTrashed + action restore و forceDelete — UX حرفه‌ای.

تفاوت Soft Delete و status=archived

archived هنوز در query عادی دیده می‌شود با فیلتر؛ soft delete از query جدا می‌شود. گاهی هر دو لازم است.

performance

index روی deleted_at برای جدول بزرگ. بهینه‌سازی.

جمع‌بندی

Soft delete برای entityهای قابل بازیابی ضروری است. global scope، Observer برای cleanup.

CMS سفارشی