Eloquent ORM

Eloquent ORM

177 Okunma Laravel Emir Gökkaya

#Eloquent ORM Giriş

Eloquent ORM, Laravel projelerimizde veritabanımızla çalışmak için basit bir ActiveRecord uygulaması sunar. Her veritabanı tablosu, o tabloyla etkileşime girmek için kullanılan ilgili bir Model'e sahiptir. Modeller, tablolarımızdaki verileri sorgulamamız ve yeni kayıtlar eklememize izin verir.

Başlamadan önce config/database.php dosyasından database ayarlarımızı yapmamız gereklidir.

 

#Model Tanımlama

Model dosyalarımız varsayılan olarak app dizininin altında oluşuyor. Fakat biz bir dizin yolu belirterek bunu değiştirebiliriz;

php artisan make:model Blog

Modeli oluştururken bir veritabanı geçişi oluşturmak istersek --migration veya -m şeçeneğini kullanabiliriz;

php artisan make:model Blog --migration
php artisan make:model Blog -m

 

#Eloquent Model Kuralları

Oluşan model dosyamıza app/Blog.php yolunu takip ederek gidelim;

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Blog extends Model
{
    //
}

Tablo İsimleri

Peki modelimiz hangi tablo ile bağlanacak ?

Laravel'de "snake case" denilen bir kavram vardır. Eğer tablo ismini biz belirtmezsek, modelin çoğul halini alan bir tabloya bağlanacaktır. Bu örnek için Blog modelimiz blogs adında bir tablo arayacaktır. Fakat bu tablo ismini kendimize göre değiştirebiliriz;

<?php
namespace App;
use Illuminate\Database\Eloquent\Model;

class Blog extends Model
{
    protected $table = 'my_blogs';
}

Primary Key(Birincil Anahtar)

Aynı şekilde primary key özelliğini de değiştirebiliriz. Varsayılan değer olarak id ismini alır, fakat biz bu özelliği manipüle edebiliriz;

<?php
namespace App;
use Illuminate\Database\Eloquent\Model;

class Blog extends Model
{
    protected $primaryKey = 'blog_id';
}

Ek olarak, Eloquent, primary key özelliğini artan bir tamsayı(integer) değeri olduğunu varsayar; bu, varsayılan olarak primary key özelliğinin otomatik olarak artan bir int öğesine atılacağı anlamına gelir. Artımlı olmayan veya sayısal olmayan bir birincil anahtar kullanmak istiyorsanız, modelimizdeli public $incrementing özelliğini false olarak ayarlamanız gerekir;

<?php
class Blog extends Model { public $incrementing = false; }

Birincil anahtarınız bir tamsayı değilse, modelinizdeki korumalı $keyType özelliğini stringolarak ayarlamalıyız;

<?php

class Blog extends Model
{
    protected $keyType = 'string';
}

Timestamps(Zaman Damgaları)

Varsayılan olarak, Eloquent, tablonuzda created_at ve updated_at sütunlarının olmasını bekler. Bu sütunların Eloquent tarafından otomatik olarak yönetilmesini istemiyorsak, modelimizdeki $timestamps özelliğini falseolarak ayarlamalıyız;

<?php

namespace App;
use Illuminate\Database\Eloquent\Model;

class Blog extends Model
{
    public $timestamps = false;
}

Timestamps değerlerini depolamak için kullanılan sütunların isimlerini de özelliştirebiliriz;

<?php

class Blog extends Model
{
    const CREATED_AT = 'olusturulma_tarihi';
    const UPDATED_AT = 'guncellenme_tarihi';
}

Fillable & Guarded

Fillable, tablomuzdaki hangi özelliklere müdahale edeceğimizi belirttiğimiz dizidir. Guarded ise tablomuzdaki korumak istediğimiz özelliklerin belirtildiği dizidir.

class Blog extends Model
{
protected $fillable = ['name', 'author', 'number', 'active'];
protected $guarded = ['votes']; }

 

#Modelden Veri Çekme

$blogs = App\Blog::where('active', 1)
               ->orderBy('name', 'desc')
               ->take(10)
               ->get();

Yukarıdaki kod bloğu tablodan, active özelliği 1 olan, ismine göre terten sıralanmış(z-a, Z-A), 10 tane sütunu getir şeklinde bir sorgu çalıştırır.

Tek Veri Çekme

// Id değeri 1 olan veriyi çeker
$blog = App\Blog::find(1);

// active değeri 1 olan verilerden birincisini çeker
$blog = App\Blog::where('active', 1)->first();

Bulunamayan İstisnalar

// Id değeri 1 olan veriyi çeker, eğer öyle bir değer yoksa ModelNotFoundException hatası döner
$model
= App\Blog::findOrFail(1); // Bloglardan number değeri 100 den büyük olan değerlerden birincisini döner, yoksa ModelNotFountException hatası döner
$model = App\Blog::where('number', '>', 100)->firstOrFail();

#Model Ekleme ve Güncelleme

Inserts

Modelden tabloya yeni bir değer eklemek için;

...
class BlogController extends Controller
{
    public function store(Request $request)
    {
        // Yeni bir blog nesnesi oluşturulur
        $blog = new Blog;
        
// Formdan gelen request değeri oluşturulan blog nesnesinin name özelliğine atanır $blog->name = $request->name;
// Yeni blog tabloya kaydedilir $blog->save(); } }

Updates

Tablodaki bir değeri güncellemek içinde save metodu kullanılır.

$$blog = App\Blog::find(1);

$blog->name = 'New Blog Name';

$blog->save();

Toplu Güncellemeler

Güncellemeler, belirli bir sorguyla eşleşen herhangi bir sayıda modele karşı da gerçekleştirilebilir.

App\Blog::where('active', 1)
          ->where('author', 'Jon')
          ->update(['active' => 0]);

Yukarıdaki örnekte Jon yazarına ait aktif blogları pasif hale getiren bir komut çalışır.

Diğer Oluşturma Yöntemleri

Modelleri toplu atama nitelikleriyle oluşturmak için kullanabileceğimiz iki yöntem daha var, firstOrCreate ve firstOrNew.

firstOrCreate metodu, verilen sütun/değer çiftlerini kullanarak bir veritabanı kaydını bulmaya çalışır. Eşleşme bulamaz ise veritabanında otomatik olarak yeni bir giriş oluşturur.

firstOrNew metodu ise firstOrFail gibi verilen niteliklerle eşleşen veri kaydını bulmaya çalışacaktır. Eşleşme bulunamaz ise çalışacak yeni bir model örneği verir.

İkisi arasında nasıl bir seçim yapmak, yapılacak işe bağlıdır. Model örneğini ilk kez kaydetmeden önce değiştirmek istiyorsak(örneğin, bir ad veya zorunlu bir alan belirleme), firstOrNew metodunu kullanmalıyız, değişkenleri veritabanında değiştirmeden, hemen yeni bir model örneği oluşturmak için firstOrCreate metodunu kullanmalıyız.

// bloğa isim ile ulaşmaya çalışır, eğer bulamaz ise oluşturur...
$blog = App\Blog::firstOrCreate(['name' => 'Partum']);

// bloğa isim ile ulaşmaya çalışır, veya name, number ve author özelliklerini oluşturur...
$blog = App\Blog::firstOrCreate(
    ['name' => 'Partum'],
    ['number' => 100, 'author' => 'Jon']
);

// bloğa isim ile ulaşmaya çalışır, eğer bulamaz ise başlatır...
$blog= App\Blog::firstOrNew(['name' => 'Partum']);

// bloğa isim ile ulaşmaya çalışır, veya name, number ve author özelliklerini başlatır...
$blog= App\Blog::firstOrNew(
    ['name' => 'Partum'],
    ['number' => 100, 'author' => 'Jon']
);

Ayrıca, mevcut bir model, güncellemek veya mevcut değilse yeni bir model oluşturmak istediğimiz durumlarda updateOrCreate metodu kullanılabilir. Bu metod aynı firstOrCreate metodu gibi save() metodunu çağırmamıza gerek duymaz;

$blog = App\Blog::updateOrCreate(
    ['name' => 'Partum Software', 'body' => '.....'],
    ['number' => 100, 'author' => 'Mike']
);

#Modelleri Silme

Bir modeli silmek için delete metodunu kullanabiliriz;

$blog = App\Blog::find(1);
$blog->delete();

Mevcut Bir Modeli Anahtar İle Silme

Yukarıdaki örnekte veri ilk önce tablodan çekiliyor ve daha sonra delete metodu ile siliniyor.

Eğer biz silinecek olan verinin anahtarını biliyorsak veriyi hiç çekmeden de silme imkanımız vardır. Argüman olarak tek bir primary key' e ek olarak,  birden çok primary key, bir primary key anahtar dizisi veya koleksiyonu olabilir.

App\Blog::destroy(1);
App\Blog::destroy(1, 2, 3);
App\Blog::destroy([1, 2, 3]);
App\Blog::destroy(collect([1, 2, 3]));

Sorgu ile silmek için;

$deletedRows = App\Blog::where('active', 0)->delete();

#Soft Deleting

Aslında veritabanınızdaki kayıtları kaldırmanın yanı sıra, Eloquent modellerine "soft deleting" de yapabilir. Modeller bu şekilde silindiğinde, aslında veritabanınızdan kaldırılmazlar. Bunun yerine, modelde bir deleted_at niteliği belirlenir ve veritabanına eklenir. Bir model boş olmayan bir deleted_at değerine sahipse, model soft deleting şekilde silinmiştir. Bir modelde soft deleting etkinleştirmek için, modeldeki Illuminate\Database\Eloquent\SoftDeletes özelliği kullanılır;

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Blog extends Model
{
    use SoftDeletes;
}

Ayrıca migrate dosyamızda soft deleting için bir sütun eklenmelidir;

Schema::table('blogs', function (Blueprint $table) {
    $table->softDeletes();
});

Modeldeki silme metodunu çağırdığımızda, deleted_at sütunu geçerli saat ve tarihe göre ayarlanacaktır. Artık bu tabloda yapılacak sorgularda çıktı olarak görünmeyeceklerdir.

Belirli bir model örneğinin bu şekilde silinip silinmediğini belirlemek için trashed  metodu kullanılır;

if ($blog->trashed()) {
    //
}

Bu yöntem ile silinmiş modelleri çöpten geri almak için aşağıdaki sorgu kullanılabilir;

$blog->restore();

Çöpteki modellerin kalıcı olarak silinmesini istiyorsak;

// Tek bir modeli sil
$blog->forceDelete();

// İlgili tüm modelleri sil
$blog->history()->forceDelete();

Eloquent ORM ile ilgili daha fazla bilgi almak için burayı ziyaret edebilirsiniz. 

Referanslarımızı incelemek ister misiniz?
Bitirmekten keyif aldığımız ve yeni tecrübeler kazandığımız projelerimiz.