Laravel: Sıfırdan İleri Seviye

Ders 7/17 1 saat 10 dk

Eloquent ORM Temelleri

Model oluşturma, CRUD operasyonları, query builder ve mass assignment.

Eloquent ORM Temelleri

Eloquent, Laravel'in ActiveRecord implementasyonudur. Her veritabanı tablosu bir Model sınıfı ile temsil edilir.

Model Oluşturma

# Temel model
php artisan make:model Post

# Migration ile birlikte
php artisan make:model Post -m

# Factory, Migration, Seeder, Controller ile
php artisan make:model Post -mfsc

# Tüm dosyalarla (Resource Controller dahil)
php artisan make:model Post --all

Model Yapısı

 'datetime',
        'is_featured' => 'boolean',
        'view_count' => 'integer',
        'meta' => 'array',  // JSON kolonlar için
    ];
    
    /**
     * Gizli alanlar (API/JSON çıktısında görünmez)
     */
    protected $hidden = [
        'created_at',
        'updated_at',
        'deleted_at',
    ];
    
    /**
     * Tarih alanları
     */
    protected $dates = [
        'published_at',
    ];
}

CRUD İşlemleri

CREATE - Kayıt Oluşturma

// Yöntem 1: create() - Mass Assignment
$post = Post::create([
    'title' => 'İlk Yazım',
    'slug' => 'ilk-yazim',
    'content' => 'İçerik...',
    'user_id' => auth()->id(),
]);

// Yöntem 2: new + save()
$post = new Post();
$post->title = 'İlk Yazım';
$post->slug = 'ilk-yazim';
$post->content = 'İçerik...';
$post->user_id = auth()->id();
$post->save();

// Yöntem 3: firstOrCreate - Yoksa oluştur
$post = Post::firstOrCreate(
    ['slug' => 'ilk-yazim'],  // Arama kriterleri
    ['title' => 'İlk Yazım', 'content' => '...']  // Oluşturulacak değerler
);

// Yöntem 4: updateOrCreate - Güncelle veya oluştur
$post = Post::updateOrCreate(
    ['slug' => 'ilk-yazim'],
    ['title' => 'Güncel Başlık', 'content' => 'Güncel içerik']
);

READ - Kayıt Okuma

// Tüm kayıtlar
$posts = Post::all();

// ID ile bulma
$post = Post::find(1);           // Bulamazsa null
$post = Post::findOrFail(1);     // Bulamazsa 404 Exception
$posts = Post::find([1, 2, 3]);  // Birden fazla

// İlk kayıt
$post = Post::first();
$post = Post::firstOrFail();

// Koşullu sorgular
$posts = Post::where('status', 'published')->get();
$posts = Post::where('status', 'published')
             ->where('user_id', 1)
             ->get();

// where operatörleri
$posts = Post::where('view_count', '>', 100)->get();
$posts = Post::where('title', 'like', '%Laravel%')->get();
$posts = Post::whereIn('status', ['published', 'draft'])->get();
$posts = Post::whereNotNull('published_at')->get();
$posts = Post::whereBetween('created_at', [$start, $end])->get();

// Sıralama
$posts = Post::orderBy('created_at', 'desc')->get();
$posts = Post::latest()->get();  // created_at desc
$posts = Post::oldest()->get();  // created_at asc

// Limit
$posts = Post::take(10)->get();
$posts = Post::limit(10)->offset(20)->get();

// Sayfalama
$posts = Post::paginate(15);
$posts = Post::simplePaginate(15);

// Aggregates
$count = Post::count();
$max = Post::max('view_count');
$avg = Post::avg('view_count');
$sum = Post::sum('view_count');

UPDATE - Güncelleme

// Yöntem 1: Tek kayıt güncelle
$post = Post::find(1);
$post->title = 'Yeni Başlık';
$post->save();

// Yöntem 2: update() metodu
$post = Post::find(1);
$post->update([
    'title' => 'Yeni Başlık',
    'content' => 'Yeni içerik',
]);

// Yöntem 3: Toplu güncelleme
Post::where('status', 'draft')
    ->update(['status' => 'archived']);

// Increment / Decrement
Post::find(1)->increment('view_count');
Post::find(1)->increment('view_count', 5);
Post::find(1)->decrement('stock');

DELETE - Silme

// Yöntem 1: delete()
$post = Post::find(1);
$post->delete();

// Yöntem 2: destroy()
Post::destroy(1);
Post::destroy([1, 2, 3]);

// Yöntem 3: Koşullu silme
Post::where('status', 'archived')->delete();

// Soft Delete (SoftDeletes trait gerekli)
$post->delete();           // deleted_at set edilir
$post->trashed();          // Silinmiş mi?
$post->restore();          // Geri yükle
$post->forceDelete();      // Kalıcı sil

// Soft deleted kayıtları dahil et
Post::withTrashed()->get();
Post::onlyTrashed()->get();

Query Scopes

// Model içinde scope tanımlama
class Post extends Model
{
    // Local scope
    public function scopePublished($query)
    {
        return $query->where('status', 'published')
                     ->whereNotNull('published_at');
    }
    
    public function scopeByAuthor($query, $userId)
    {
        return $query->where('user_id', $userId);
    }
    
    public function scopePopular($query, $minViews = 100)
    {
        return $query->where('view_count', '>=', $minViews);
    }
}

// Kullanım
$posts = Post::published()->get();
$posts = Post::published()->byAuthor(1)->get();
$posts = Post::published()->popular(500)->latest()->get();

Accessors & Mutators (Laravel 9+)

use Illuminate\Database\Eloquent\Casts\Attribute;

class Post extends Model
{
    // Accessor: Veritabanından okurken dönüştür
    protected function title(): Attribute
    {
        return Attribute::make(
            get: fn ($value) => ucfirst($value),
        );
    }
    
    // Mutator: Veritabanına yazarken dönüştür
    protected function slug(): Attribute
    {
        return Attribute::make(
            set: fn ($value) => Str::slug($value),
        );
    }
    
    // Her ikisi birden
    protected function name(): Attribute
    {
        return Attribute::make(
            get: fn ($value) => ucfirst($value),
            set: fn ($value) => strtolower($value),
        );
    }
    
    // Virtual attribute (veritabanında yok)
    protected function fullName(): Attribute
    {
        return Attribute::make(
            get: fn () => $this->first_name . ' ' . $this->last_name,
        );
    }
}

Önemli Noktalar

  • Her veritabanı tablosu bir Model ile temsil edilir
  • $fillable veya $guarded ile mass assignment koruması
  • find(), first(), get(), all() ile veri çekme
  • create(), update(), delete() ile veri manipülasyonu
  • Query Builder zincirleme metodlarla sorgu oluşturur