Laravel Soft Delete
Bugün biraz daha özel bir konudan bahsedeceğiz. Veritabanımızda ki verilerimizin tamamen silinmesi genel olarak istemediğimiz bir durumdur. Bu sebeple Laravel üzerinde Soft Delete konusundan bahsedeceğiz.
“Not: Anlatımı blog makale sistemi üzerinden anlatacağım. Bir Laravel Projesi oluşturduğunuzu düşünerek anlatıma devam ediyorum. Anlatım esnasında bir tasarım deseni vb. şeyler kullanmayacağım. Sadece Soft Delete konusundan bahsedeceğim. ”
Öncelikli olarak birkaç rota tanımlayalım.
# /routes/api.phpRoute::group(['prefix'=>'blog'], static function(){
Route::get('all','BlogController@all');
Route::get('list','BlogController@list');
Route::get('only-trashed','BlogController@onlyTrashed');
Route::post('store','BlogController@store');
Route::delete('delete/{id}','BlogController@delete');
Route::patch('restore/{id}','BlogController@restore');
});
Öncelikli olarak bir ön ek ekledik Blog adında ve bunun içerisinde
- Listele
- Sadece Silinenleri listele
- Kaydet
- Sil
- Geri ekle
Şeklinde işlemlerimizi tanımlamış olduk. Şimdi bir tane Model ve buna bağlı Controller ve Migration dosyalarımızı oluşturalım.
# /bash
php artisan make:model Blog -mc
Sonrasında Controller içerisinde metotlarımızı tanımlayalım. Düzenlemelerden sonra BlogController şöyle görünüyor olmalı.
<?php
namespace App\Http\Controllers;
use App\Http\Requests\StoreRequest;
class BlogController extends Controller
{
public function all()
{ }
public function list()
{
}
public function store(StoreRequest $request)
{
}
public function delete(Int $id)
{
}
public function restore(Int $id)
{
}
public function onlyTrashed()
{
}
}
Burada Kontrol işlemlerini rahat yapabilmek için FormRequest özelliğinden yararlandım. Bilmeyenler buradan daha önceki makaleme göz atabilir. Sonrasında migration dosyamızı düzenliyoruz ve ardından çalıştırıyoruz.
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateBlogsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('blogs', function (Blueprint $table) {
$table->id();
$table->string('title',60);
$table->text('content');
$table->integer('views',false)->default(0);
$table->string('author');
$table->timestamps();
/**
* Bu kısım soft-delete özelliğini kullanabilmemiz için gerekli.
*/
$table->softDeletes();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('blogs');
}
}
Burada eklediğimiz softDeletes metodu blogs tablosuna deleted_at adından bir kolon oluşturmak için gerekiyor. Bu sayede soft-delete özelliğimizi kullanabileceğiz.Ardından Model dosyamızı aşağıdaki gibi güncelliyoruz.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Blog extends Model
{
use SoftDeletes;
protected $fillable = [
'title','content','author'
];
}
Burada SoftDelete trait bizim için deleted_at kolonunu ve diğer özellikleri yönetecek. Şimdi Controller içine oluşturduğumuz metotları dolduralım. Şu şekilde görünüyor olmalı.
<?php
namespace App\Http\Controllers;
use App\Http\Requests\{StoreRequest};
use App\Blog;
use Illuminate\Http\JsonResponse;
class BlogController extends Controller
{
/**
* Silinenler dahil tüm yazıları getirir.
* @return JsonResponse
*/
public function all()
{
/**
* withTrashed ile sorguya silinen yazılarıda eklemiş olduk.
*/
$blogs = Blog::withTrashed()->get();
return response()->json($blogs,200);
}
/**
* @return JsonResponse
* Silinenler hariç tüm blog yazılarını getirir.
*/
public function list()
{
return response()->json( Blog::all() , 200);
}
/**
* @param StoreRequest $request
* Yeni bir blog yazısı kayıt eder.
* @return JsonResponse
*/
public function store(StoreRequest $request)
{
$store = [
'title' => $request->post('title'),
'content' => $request->post('content'),
'author' => $request->post('author') ?? "Anonymous",
];
$result = Blog::create( $store );
return response()->json($result,200);
}
/**
* Bir blog yazısını siler.
* @param Int $id
* @return JsonResponse
*/
public function delete(Int $id)
{
$blog = Blog::findOrFail($id);
$blog->delete();
return response()->json(['deleted_at' => $blog->deleted_at],200);
}
/**
* Silinen bir blog yazısını geri getirir.
* @param Int $id
* @return JsonResponse
*/
public function restore(Int $id)
{
/**
* Sadece silinenler arasından içeriği bul.
*/
$blog = Blog::onlyTrashed()->findOrFail($id);
$blog->restore();
return response()->json($blog,200);
}
/**
* Sadece silinen blog yazılarını getirir.
*/
public function onlyTrashed()
{
/**
* Burada ekstra olarak onlyTrashed çağırıyoruz.
*/
$blog = Blog::onlyTrashed()->get();
return response()->json($blog,200);
}
}
Böylelikle işlemlerimizi tamamlamış olduk. Burada asıl dikkat edilmesi gereken iki tane metot var bunlardan bir tanesi withTrashed() bu metot yapılan sorguya silinenleride dahil etmemizi sağlıyor. Bir diğeri ise sadece silinenleri getirmek için kullandığımız onlyTrashed() metodu. Eğer gerçekten veritabanınızdan kaldırmak istiyorsanız forceDelete kullanabilirsiniz ama önermiyorum. Burada yazımızın sonuna geldik.
Bir sonraki yazılarımdan haberdar olmak için Medium Hesabımı takip edebilirsiniz.
Projeye ait postman koleksiyonuna buradan erişebilirsiniz.
Projenin tamamına github üzerinden erişebilirsiniz.
Herkese İyi ve Hatasız Kodlamalar :)
Tolga Karabulut
tolga.karabulut@medianova.com
Medianova CDN | Senior PHP Developer