Laravel中如何通过修改删除状态实现可恢复的伪删除
Hey there! Looks like you want to set up non-permanent deletion (soft deletion) for your Account records using a deletion status field instead of permanently wiping them. Let's tweak your existing destroy method to make that happen, plus cover a few extra tips to keep this working smoothly.
Step 1: Make Sure Your Table Has a Deletion Status Field
First, confirm your accounts database table has a field to track deletion status. A common choice is a boolean field like is_deleted (default value false to represent active records). If you don't have this field yet, create a migration:
php artisan make:migration add_is_deleted_to_accounts_table --table=accounts
Open the generated migration file and add the field:
public function up() { Schema::table('accounts', function (Blueprint $table) { $table->boolean('is_deleted')->default(false); }); } public function down() { Schema::table('accounts', function (Blueprint $table) { $table->dropColumn('is_deleted'); }); }
Run the migration to apply the change:
php artisan migrate
Step 2: Revise the destroy Method
Your current method uses Laravel's default delete() which permanently removes the record. Instead, we'll update the is_deleted field to mark the record as "deleted". Also, since you're using route model binding, the $account variable is already a loaded instance—you don't need to call Account::find($account->id) again.
Here's the updated method:
public function destroy(Account $account) { // Update the deletion status to mark the account as "deleted" $updateSuccess = $account->update(['is_deleted' => true]); if ($updateSuccess) { return redirect()->route('account.index') ->with('success', 'Account details marked as deleted successfully!'); } return back()->withInput() ->with('error', 'Account details could not be marked as deleted. Please try again.'); }
Quick Customization Note
If you're using a different status field (e.g., status where 1 = active, 2 = deleted), just adjust the update array to match your field name and value:
$updateSuccess = $account->update(['status' => 2]);
Step 3: Filter Out "Deleted" Records by Default
To ensure your app doesn't show deleted accounts in regular views, add a global scope to your Account model. This automatically excludes marked-as-deleted records from all default queries:
// In your Account model protected static function booted() { static::addGlobalScope('active', function ($query) { $query->where('is_deleted', false); }); }
If you ever need to retrieve deleted accounts (for recovery), you can bypass the scope:
// Get all accounts, including deleted ones $allAccounts = Account::withoutGlobalScope('active')->get(); // Get a specific deleted account $deletedAccount = Account::withoutGlobalScope('active')->find($accountId);
Step 4: Add Account Recovery (Bonus)
If you want to let users restore deleted accounts, create a separate method to reset the is_deleted field back to false:
public function restore(Account $account) { $restoreSuccess = $account->update(['is_deleted' => false]); if ($restoreSuccess) { return redirect()->route('account.index') ->with('success', 'Account restored successfully!'); } return back()->withInput() ->with('error', 'Account could not be restored. Please try again.'); }
Don't forget to add a corresponding route for this method in your web.php!
内容的提问来源于stack exchange,提问作者MJ DEV

