- Giriş
- Temel Kullanım
- Toplu Atama
- Ekleme, Güncelleme, Silme
- Belirsiz Silme
- Zaman Damgaları
- Sorgu Kapsamları
- İlişkiler
- İlişkilerin Sorgulanması
- Ateşli Yükleme
- İlişkili Modelleri Ekleme
- Ebeveyn Zaman Damgalarına Dokunma
- Pivot Tablolarla Çalışmak
- Koleksiyonlar
- Erişimciler & Değiştiriciler (Accessors & Mutators)
- Tarih Değiştiricileri
- Model Olayları
- Model Gözlemcileri
- Diziye / JSON'a Çevirme
Laravelle gelen "Eloquent ORM", veritabanınızla çalışırken kullanacağınız güzel ve sade bir ActiveRecord uygulaması sağlamaktadır. Her veritabanı tablosu, bu tabloyla etkilişim için kullanıcak kendine has bir "Model" sahibidir.
Başlamadan önce, app/config/database.php
'de bir veritabanı bağlantısı yapılandırmış olun.
Öncelikle bir Eloquent modeli oluşturunuz. Modeller tipik olarak app/models
klasöründe yer alır, fakat siz modellerinizi composer.json
dosyanıza göre otomatik yükleme yapabileceğiniz başka bir yere de koyabilirsiniz.
Bir Eloquent Modelinin Tanımlanması
class Uye extends Eloquent {}
Dikkat ederseniz Eloquent'e Uye
modelimiz için hangi tabloyu kullanacağımızı söylemedik. Eğer açıkça başka bir isim belirtilmezse tablo isimi olarak sınıf adının ingilizde çoğulunun küçük harf hali kullanılacaktır. Dolayısıyla bizim örneğimizde Eloquent, Uye
modelinin uyes
tablosundaki kayıtları tutacağını varsayacaktır. Tablo ismini açıkça belirtmek için modelinizde bir table
özelliği tanımlayınız:
class Uye extends Eloquent {
protected $table = 'uyeler';
}
Not: Eloquent'in başka bir ön kabulü de her tablonun
id
adında bir primer key sütunu olduğudur. Bu kuralı aşmak için de birprimaryKey
özelliği tanımlamanız gerekecek. Benzer şekilde, modeliniz kullanılacağı zaman kullanılacak veritabanı bağlantısının adını değiştirmek için birconnection
özelliği tanımlayabilirsiniz.
Bir model tanımladıktan sonra artık tablonuzda kayıt oluşturmaya ve ondan kayıt getirmeye başlayabilirsiniz. Tablolarınıza ön tanımlı olarak updated_at
ve created_at
sütunları koymanız gerektiğine dikkat ediniz. Şayet bu sütunların otomatik olarak tutulmasını istemiyorsanız, modelinizdeki $timestamps
özelliğini false
olarak ayarlayınız.
Tüm Modellerin Alınması
$uyeler = Uye::all();
Birincil Alana Göre Bir Kaydın Alınması
$uye = Uye::find(1);
var_dump($uye->isim);
Not: Sorgu Oluşturucusu'nda bulunan tüm metodlar Eloquent modellerini sorgularken de kullanılabilir.
Birincil Alana Göre Bir Model Alınması ya da Ortaya Bir İstisna Çıkartılması
Bazı durumlarda bir model bulunamadığında bir istisna çıkartmak, böylece bir App::error
işleyicisi kullanarak istisnayı yakalayabilmek ve bir 404 sayfası göstermek isteyebilirsiniz.
$model = Uye::findOrFail(1);
Bu hata işleyicinin kaydını yapmak için ModelNotFoundException
'i dinlemek lazım.
use Illuminate\Database\Eloquent\ModelNotFoundException;
App::error(function(ModelNotFoundException $e)
{
return Response::make('Bulunamadı', 404);
});
Eloquent Modelleri Kullanarak Sorgu Yapma
$uyeler = Uye::where('puan', '>', 100)->take(10)->get();
foreach ($uyeler as $uye)
{
var_dump($uye->isim);
}
Tabi ki, sorgu oluşturucusunun kümeleme fonksiyonlarını da kullanabilirsiniz.
Eloquent Küme Metodları
$adet = Uye::where('puan', '>', 100)->count();
Yeni bir model oluşturulurken model oluşturucuya niteliklerden oluşan bir dizi geçersiniz. Bu nitelikler bu durumda modele "toplu atama" aracılığıyla atanır. Bu gayet uygun bir yaklaşımdır, fakat bir kullanıcı girdisi bir modele körleme geçirildiği takdirde ciddi (serious) bir güvenlik sorunu olabilecektir. Kullanıcı girdisi bir modele körlemesine geçirilirse, bu kullanıcı modelin niteliklerinin birisini (any) ve hepsini (all) değiştirebilecektir. Bu sebepler yüzünden, tüm Eloquent modelleri ön tanımlı olarak toplu atamaya karşı koyar.
Başlamak için modelinizde fillable
veya guarded
özelliğini ayarlayınız.
Bunlardan fillable
özelliği hangi niteliklerin toplu atanacaklarını belirler. Bu işlem sınıf ya da olgu düzeyinde ayarlanabilir.
Bir Modelde Fillable Niteliklerin Tanımlanması
class Uye extends Eloquent {
protected $fillable = array('ismi', 'soy_ismi', 'email');
}
Bu örnekte, sadece belirttiğimiz üç nitelik toplu atanabilecektir.
fillable
'in tersi guarded
'dir ve bir "beyaz-liste" yerine bir "kara-liste" olarak iş görür:
Bir Modelde Guarded Niteliklerin Tanımlanması
class Uye extends Eloquent {
protected $guarded = array('id', 'parola');
}
Yukardaki örneğe göre id
ve parola
nitelikleri toplu atana mayacaktır. Diğer tüm nitelikler toplu atanabilecektir. Toplu atamayı niteliklerin hepsi (all) için bloke etmeyi de seçebilirsiniz:
Toplu Atamanın Tüm Nitelikler İçin Engellenmesi
protected $guarded = array('*');
Veritabanında bir modelden yeni bir kayıt oluşturmak için, yeni bir model olgusu oluşturun ve save
metodunu çağırın.
Yeni Bir Modelin Kaydedilmesi
$uye = new Uye;
$uye->isim = 'Can';
$uye->save();
Not: Tipik olarak, Eloquent modellerinizde otomatik artan anahtarlar olacaktır. Ama siz kendi keylerinizi belirlemek isterseniz, modelinizdeeki
incrementing
özelliğinifalse
olarak ayarlayın.
Yeni bir modeli tek satırda kaydetmek için create
metodunu kullanabilirsiniz. Eklenen model olgusu bu metoddan döndürülecektir. Ancak, tüm Elequent modelleri toplu atamaya karşı korunumlu oldukları için, bunu yapmadan önce modelinizde bir fillable
veya guarded
özelliği belirlemeniz gerekecektir.
Modeldeki Korunumlu Niteliklerin Ayarlanması
class Uye extends Eloquent {
protected $guarded = array('id', 'hesap_no');
}
Model Create Metodunun Kullanımı
$uye = Uye::create(array('isim' => 'Can'));
Bir modeli güncellemek için onu getirir, bir niteliğini değiştirir, sonra da save
metodunu kullanabilirsiniz:
Getirilen Bir Modelin Güncellenmesi
$uye = Uye::find(1);
$uye->email = '[email protected]';
$uye->save();
Bazen sadece bir modeli değil, onun bütün ilişkilerini de kaydetmek isteyebilirsiniz. Bunu yapmak için push
metodunu kullanın:
Bir Model ve İlişkilerinin Kaydedilmesi
$uye->push();
Ayrıca, bir modeller kümesinde güncelleme sorguları da çalıştırabilirsiniz:
$satirSayisi = Uye::where('puan', '>', 100)->update(array('durum' => 2));
Bir modeli silmek için olgu üzerinde delete
metodunu çağırın:
Mevcut Bir Modelin Silinmesi
$uye = Uye::find(1);
$uye->delete();
Mevcut Bir Modelin Key Aracılığıyla Silinmesi
Uye::destroy(1);
Uye::destroy(1, 2, 3);
Gayet tabii, bir modeller kümesinde bir silme sorgusu da çalıştırabilirsiniz:
$satirSayisi = Uye::where('puan', '>', 100)->delete();
Eğer bir modelde sadece zaman damgalarını güncellemek istiyorsanız, touch
metodunu kullanabilirsiniz:
Bir Modelin Sadece Zaman Damgalarının Güncellenmesi
$uye->touch();
Ön tanımlı olarak, veritabanı tablonuzdaki created_at
ve updated_at
sütunlarının idamesini otomatik olarak Eloquent yapacaktır. Size tek düşen datetime
tipindeki bu iki alanı tablonuza eklemektir, geri kalan işleri Eloquent üstlenecektir. Şayet siz bu sütunların idamesini Eloquent'in yapmasını istemiyorsanız, modelinize şu özelliği eklemeniz gerekir:
Otomatik Zaman Damgalarının Devre Dışı Bırakılması
class Uye extends Eloquent {
protected $table = 'uyeler';
public $timestamps = false;
}
Zaman damgalarınızın biçimini özelleştirmek isterseniz, modelinizdeki freshTimestamp
metodunu ezebilirsiniz(override):
Özel Bir Zaman Damgası Biçiminin Şart Koşulması
class Uye extends Eloquent {
public function freshTimestamp()
{
return time();
}
}
Bir model belirsiz silindiğinde, aslında veritabanınızdan çıkartılmaz. Onun yerinde kayıttaki bir deleted_at
zaman damgası ayarlanır. Bir modeli için belirsiz silmeler yapılabilmesi için modelinizde softDelete
özelliğine atama yapmanız gerekir:
class Uye extends Eloquent {
protected $softDelete = true;
}
Tablonuza bir deleted_at
sütunu eklemek için ise, bir migrasyondan softDeletes
metodunu kullanabilirsiniz:
$table->softDeletes();
Şimdi, artık modelinizde delete
metodunu çağırdığınız zaman, bu deleted_at
sütunu güncel zaman damgasına ayarlanacaktır. Belirsiz silme kullanılan bir model sorgulandığında, "silinmiş olan" modeller sorgu sonuçlarına dahil edilmeyecektir. Bir sonuç kümesinde belirsiz silinmiş modellerin gözükmesini zorlamak için sorgunuzda withTrashed
metodunu kullanınız:
Belirsiz Silinmiş Modelleri Sonuçlara Girmeye Zorlama
$uyeler = Uye::withTrashed()->where('hesap_no', 1)->get();
Sonuç kümenizde sadece belirsiz silinmiş modellerin olmasını istiyorsanız, onlyTrashed
metodunu kullanabilirsiniz:
$uyeler = Uye::onlyTrashed()->where('hesap_no', 1)->get();
Belirsiz silinmiş bir modeli tekrar etkin hale getirmek için, restore
metodunu kullanın:
$uye->restore();
restore
metodunu bir sorguda da kullanabilirsiniz:
Uye::withTrashed()->where('hesap_no', 1)->restore();
restore
metodu ilişkilerde de kullanılabilir:
$uye->postalar()->restore();
Bir modeli veritabanından gerçekten çıkartmak istediğinizde, forceDelete
metodunu kullanabilirsiniz:
$uye->forceDelete();
forceDelete
metodu ilişkilerde de çalışır:
$uye->postalar()->forceDelete();
Belli bir model olgusunun belirsiz silme özelliğine sahip olup olmadığını öğrenmek için, trashed
metodunu kullanabilirsiniz:
if ($uye->trashed())
{
//
}
Kapsamlar size sorgu mantığınızı modellerinizde tekrar tekrar kullanma imkanı verir. Bir kapsam tanımlamak için bir model metodunun başına scope
getirmeniz yeterlidir:
Bir Sorgu Kapsamının Tanımlanması
class Uye extends Eloquent {
public function scopePopular($query)
{
return $query->where('puan', '>', 100);
}
}
Bir Sorgu Kapsamının Kullanılması
$uyeler = Uye::popular()->orderBy('created_at')->get();
Pek tabii, veritabanı tablolarınız büyük ihtimalle bir diğeriyle ilişkilidir. Örneğin bir blog yazısında çok sayıda yorum olabilir veya bir sipariş onu ısmarlayan kullanıcı ile ilişkili olacaktır. Eloquent bu ilişkileri kolayca yönetmenizi ve rahat çalışmanızı sağlar. Laravel dört tip ilişkiyi desteklemektedir:
Birden bire şeklindeki bir ilişki çok basit bir ilişikidir. Örneğin, bir Uye
modelinin bir Telefon
'u olabilir. Eloquent'de bu ilişkiiyi şöyle tanımlayabiliriz:
Birden Bire Tarzı İlişki Tanımlama
class Uye extends Eloquent {
public function tel()
{
return $this->hasOne('Telefon');
}
}
hasOne
metoduna geçirilen ilk parametre ilişkili modelin adıdır. İlişki tanımlandıktan sonra onu Eloquent'in dinamik özellikler'ini kullanarak elde edebiliriz:
$tel = Uye::find(1)->tel;
Bu cümlenin gerçekleştirdiği SQL şunlardır (tablo isimleri model tanımında özel olarak belirtilmedi ise tablo ismi olarak model isminin küçük harfli çoğul halinin kullanıldığını hatırlayınız):
select * from uyes where id = 1
select * from telefons where uye_id = 1
Eloquent'in ilişkideki yabancı key'in ne olduğuna model adına göre karar verdiğine dikkat ediniz. Şimdiki örnekte Telefon
modelinin uye_id
adlı bir yabancı key kullandığı varsayılmaktadır. Siz nu ön kuralı değiştirmek istiyorsanız hasOne
metoduna ikinci bir parametre geçebilirsiniz:
return $this->hasOne('Telefon', 'mahsus_key');
Telefon
modeli üzerinde ilişkinin tersini tanımlamak için, belongsTo
metodunu kullanınız:
Bir İlişkinin Tersinin Tanımlanması
class Telefon extends Eloquent {
public function uye()
{
return $this->belongsTo('Uye');
}
}
Birde birçoğa ilişki örneği olarak birçok yorum yapılmış bir blog yazısı verilebilir. Bu ilişkiyi de şöyle modelleyebiliriz:
class Makale extends Eloquent {
public function yorumlar()
{
return $this->hasMany('Yorum');
}
}
Şimdi artık bir makalenin yorumlarına dinamik özellik aracılığıyla ulaşabiliriz:
$yorumlar = Makale::find(1)->yorumlar;
Hangi yorumların alınacağını daha da kısıtlamak için yorumlar
metodunu çağırabilir ve şartlar koşmayı sürdürebilirsiniz:
$yorumlar = Makale::find(1)->yorumlar()->where('baslik', '=', 'bu')->first();
Tıpkı hasOne'de olduğu gibi konvansiyonel yabancı key varsayımını hasMany
metoduna ikinci bir parametre geçerek değiştirebilirsiniz:
return $this->hasMany('Yorum', 'mahsus_key');
İlişkinin tersini Yorum
modelinde tanımlamak için, belongsTo
metodu kullanılmaktadır:
Bir İlişkinin Tersinin Tanımlanması
class Yorum extends Eloquent {
public function makale()
{
return $this->belongsTo('Makale');
}
}
Birçoktan birçoğa ilişkiler daha karmaşık bir ilişki tipidir. Bu tarz bir ilişki örneği bir üyenin birçok rolü olması, aynı zamanda bu rollerin başka kullanıcılar tarafından da paylaşılmasıdır. Örneğin birçok üye "Müdür" rolünde olabilir. Bu ilişki için üç veritabanı tablosu gereklidir: uyeler
, roller
ve rol_uye
. Bu rol_uye
tablosu ilişkili model isimlerinin alfabetik sıralamasına göre adlandırılır ve uye_id
ve rol_id
sütunlarına sahip olmalıdır (model isimlerine alttire ve id eklenmiş iki alan).
Birçoktan birçoğa ilişikileri belongsToMany
metodunu kullanarak tanımlayabiliyoruz:
class Uye extends Eloquent {
public function roller()
{
return $this->belongsToMany('Rol');
}
}
Artık rolleri Uye
modeli aracılığıyla getirebiliriz:
$roller = Uye::find(1)->roller;
Pivot tablo ismi olarak ön kabullü tablo ismi yerine başka bir isim kullanmak isterseniz, bunu belongsToMany
metoduna ikinci bir parametre geçerek gerçekleştirebilirsiniz:
return $this->belongsToMany('Rol', 'uye_rollleri');
İlişkili key için konvansiyonel yaklaşımı da değiştirebilirsiniz:
return $this->belongsToMany('Rol', 'uye_rollleri', 'user_id', 'foo_id');
Ve tabii ki ilişkinin tersini Rol
modelinde de tanımlayabilirsiniz:
class Rol extends Eloquent {
public function uyeler()
{
return $this->belongsToMany('Uye');
}
}
Çokbiçimli (Polimorfik) İlişkiler bir modelin tek bir ilişkilendirme ile birden çok modele ait olmasına imkan verir. Örneğin, kendisi ya bir personel modeline ya da bir siparis modeline ait olan bir foto modeliniz olduğunu düşünün. Bu ilişkiyi şu şekilde tanımlayacağız:
class Foto extends Eloquent {
public function resim()
{
return $this->morphTo();
}
}
class Personel extends Eloquent {
public function fotolar()
{
return $this->morphMany('Foto', 'resim');
}
}
class Siparis extends Eloquent {
public function fotolar()
{
return $this->morphMany('Foto', 'resim');
}
}
Artık bir personel ya da siparişe ait fotoları elde edebiliriz:
Çokbiçimli Bir İlişkinin Getirilmesi
$personel = Personel::find(1);
foreach ($personel->fotolar as $foto)
{
//
}
Ancak, "çokbiçimli" ilişkinin gerçek farkını bir personel veya siparişe Foto
modelinden erişebilmekle görürsünüz:
Çokbiçimli Bir İlişkinin Sahibinin Getirilmesi
$foto = Foto::find(1);
$resim = $foto->resim;
Foto
modelindeki resim
ilişkisi, fotonun sahibi olan modele bağlı olarak ya bir Personel
ya da bir Siparis
olgusu döndürecektir.
Bunun nasıl çalıştığını anlamanıza yardımcı olmak için veritabanı yapımızı polimorfik bir ilişkiye açalım:
Polymorphic Relation Table Structure
personel
id - integer
isim - string
siparisler
id - integer
fiyat - integer
fotolar
id - integer
dosyayolu - string
resim_id - integer
resim_type - string
Buradaki anahtar alanların The key fields to notice here are the on the fotolar
tablosundaki resim_id
and resim_type
olduğuna dikkat ediniz. Buradaki ID, fotonun sahibi olan personel veya siparişin ID'ini, TYPE ise sahip olan modelin sınıf adını tutacaktır. Böylece ORM, resim
ilişkisiyle erişildiğinde döndürülecek sahip modelin hangisi olduğunu tespit edebilecektir.
Bir modelin kayıtlarına erişirken, sonuçları bir ilişki varlığına göre sınırlamak isteyebilirsiniz. Diyelim ki, en az bir yorum yapılmış tüm blog makalelerini çekmek istediniz. Bunu yapmak için has
metodunu kullanabilirsiniz:
Seçerken İlişkilerin Yoklanması
$makaleler = Makale::has('yorumlar')->get();
Ayrıca, bir işlemci ve bir sayı da belirleyebilirsiniz, örneğin üç ve daha çok yorum almış makaleleri getirmek için:
$makaleler = Makale::has('yorumlar', '>=', 3)->get();
Eloquent, ilişkilerinize dinamik özellikle yoluyla erişme imkanı verir. Eloquent ilişkiyi sizin için otomatik olarak yükleyecektir. Hatta, get
(birden birçoğa ilişkiler için) metodunun mu yoksa first
(birden bire ilişkiler için) metodunun mu çağırılacağını bilecek kadar akılllıdır. İlişkiyle aynı isimli dinamik bir özellik aracılığı ile erişileblir olacaktır. Örneğin, şu $telefon
modelinde:
class Telefon extends Eloquent {
public function uye()
{
return $this->belongsTo('Uye');
}
}
$telefon= Telefon::find(1);
Bu kullanının email'ini şu şekilde göstermek yerine:
echo $telefon->uye()->first()->email;
Buradaki gibi basit bir hale kısaltılabilir:
echo $telefon->uye->email;
Ateşli yükleme N + 1 sorgu problemini gidermek içindir. Örnek olarak, Yazar
ile ilişkilendirilmiş bir Kitap
modelini düşünün. İlişki de şöyle tanımlanmış olsun:
class Kitap extends Eloquent {
public function yazar()
{
return $this->belongsTo('Yazar');
}
}
Şimdi, şu kodu ele alalım:
foreach (Kitap::all() as $kitap)
{
echo $kitap->yazar->isim;
}
Bu döngü tablodaki kitapların hepsini almak için 1 sorgu çalıştıracak, sonra da yazarını elde etmek için her bir kitabı sorgulayacaktır. Yani, eğer 25 kitabımız varsa bu döngü 26 sorgu çalıştıracaktır.
Neyseki, sorgu sayısını büyük ölçüde azaltan ateşli yükleme kullanabiliriz. Ateşli yüklenecek ilişkiler with
metodu aracılığıyla belirlenebilmektedir:
foreach (Kitap::with('yazar')->get() as $kitap)
{
echo $kitap->yazar->isim;
}
Yukardaki döngüde sadece iki sorgu çalıştırılacaktır (model tanımında tablo isimleri açıkça belirtilmediyse ingilizce küçük harf çoğul kabulünü hatorlayınız):
select * from kitaps
select * from yazars where id in (1, 2, 3, 4, 5, ...)
Ateşli yüklemenin akıllıca kullanımı uygulamanızın performansını önemli ölçüde artırabilir.
Tabii ki, bir defada birden çok ilişkiyi ateşli yükleyebilirsiniz:
$kitaplar = Kitap::with('yazar', 'kitabevi')->get();
Hatta içi içe ilişkileri de ateşleyebilirsiniz:
$kitaplar = Kitap::with('yazar.kisiler')->get();
Yukarıdaki örnekte yazar
ilişkisi ateşli yüklenecektir ve yazarın kisiler
ilişkisi de ateşli yüklenecektir.
Bazen bir ilişkiyi ateşli yüklemek, ama ateşli yükleme için de bir şart belirlemek isteyebiliriz. İşte bir örnek:
$uyeler = Uye::with(array('makaleler' => function($query)
{
$query->where('baslik', 'like', '%birinci%');
}))->get();
Bu örnekte üyenin makalelerinden sadece baslik alaninda "birinci" kelimesi geçen makalelerini ateşli yüklüyoruz.
İlişkili modelleri, direkt olarak önceden mevcut model koleksiyonundan ateşli yüklemek de mümkündür. Bu özellikle ilişkili modeli önbellekleme ile birlikte yükleyip yüklememeye dinamik karar vereceğiniz zaman işe yarayabilir.
$kitaplar= Kitap::all();
$kitaplar->load('yazar', 'kitabevi');
Yeni ilişkili model ekleme ihtiyacınız çok olacaktır. Örneğin, bir makale için yeni bir yorum eklemek isteyebilirsiniz. Model üzerinde makale_id
yabancı key alanını elle ayarlamak yerine, doğrudan ebeveyn Makale
modelinden yeni yorum ekleyebilirsiniz:
İlişkili Bir Modelin Eklenmesi
$yorum = new Yorum(array('mesaj' => 'Yeni bir yorum.'));
$makale = Makale::find(1);
$yorum = $makale->yorumlar()->save($yorum);
Bu örnekte eklenen yorumdaki makale_id
alanı otomatik olarak ayarlanmaktadır.
Birçoktan birçoğa ilişkilerle çalışırken de ilişkili model ekleyebilirsiniz. Daha önceki örneğimiz Uye
ve Rol
modellerini kullanamaya devam edelim. Bir uyeye yeni roller eklemeyi attach
metodu ile yapabiliriz:
Birçoktan Birçoğa Modellerinin Eklenmesi
$uye = Uye::find(1);
$uye->roller()->attach(1);
İlişkiler için pivot tabloda tutulan nitelelikleri bir diz olarak da geçebilirsiniz:
$uye->roller()->attach(1, array('sonaerme' => $sonaerme));
Tabii, attach
'in ters işlemi detach
'tir:
$uye->roller()->detach(1);
İlişkili modelleri bağlamak için sync
metodunu da kullanabilirsiniz. Bu sync
metodu parametre olarak pivot tablodaki yerlerin id'lerinden oluşan bir dizi geçirilmesini ister. Bu işlem tamamlandıktan sonra, model için kullanıcak ara tabloda sadece bu id'ler olacaktır:
Birçoktan Birçoğa Model Bağlamak İçin Sync Kullanımı
$uye->roller()->sync(array(1, 2, 3));
Belli id değerleri olan başka pivot tabloyu da ilişkilendirebilirsiniz:
Sync Yaparken Pivot Veri Eklenmesi
$uye->roller()->sync(array(1 => array('sonaerme' => true)));
Bazen yeni bir ilişkili model oluşturmak ve tek bir komutla bunu eklemek isteyebilirsiniz. Bu işlem için, save
metodunu kullanabilirsiniz:
$rol = new Rol(array('isim' => 'Editor'));
Uye::find(1)->roller()->save($rol);
Bu örnekte, yeni bir Rol
modeli kaydedilecek ve uye modeline eklenecektir. Bu işlem için bağlı tablolardaki niteliklerden oluşan bir dizi de geçebilirsiniz:
Uye::find(1)->roller()->save($rol, array('sonaerme' => $sonaerme));
Bir Yorum
'un bir Makale
'ye ait olması örneğimizdeki gibi, bir model başka bir modele ait (belongsTo
) olduğu takdirde, çocuk modeli güncellediğiniz zaman ebeveyn zaman damgasını da güncellemek iyidir. Örneğin, bir Yorum
güncellendiğinde, bunun sahibi olan Makale
'nin updated_at
zaman damgasını otomatikman güncellemek isteyebilirsiniz. Bunu gerçekleştirmek için tek yapacağınız şey, çocuk modele ilişkilerin isimlerini içeren bir touches
özelliği eklemektir:
class Yorum extends Eloquent {
protected $touches = array('makale');
public function makale()
{
return $this->belongsTo('Makale');
}
}
Bunu yaptıktan sonra artık bir Yorum
güncellediğinizde, sahibi olan Makale
de güncellenmiş bir updated_at
sütununa sahip olacaktır:
$yorum = Yorum::find(1);
$yorum->text = 'Bu yorumu düzelt!';
$yorum->save();
Daha önce öğrendiğiniz gibi, birçoktan birçoğa ilişkilerle çalışmak bir ara tablonun olmasını gerektirir. Eloquent işte bu tablo ile etkileşim için çok yararlı bazı yollar sağlamaktadır. Örneğin bizim bir Uye
nesnemiz, bir de onun bağlı olduğu birçok Rol
nesnelerimiz olsun. Bu ilişkiye eriştikten sonra, pivot
tabloya modellerimiz üzerinden erişebiliriz:
$uye = Uye::find(1);
foreach ($uye->roller as $rol)
{
echo $rol->pivot->created_at;
}
Dikkat ederseniz, elde ettiğimiz her bir Rol
modeline otomatikman bir pivot
niteliği atanmıştır. Bu nitelik, ara tabloyu temsil eden bir modeli taşır ve herhangi bir Eloquent modeli gibi kullanılabilir.
Ön tanımlı olarak, pivot
nesnesinde sadece keyler olacaktır. Şayet pivot tablonuzda bunlardan başka nitelikler varsa, bunları ilişki tanımlama sırasında belirtmelisiniz:
return $this->belongsToMany('Rol')->withPivot('falan', 'filan');
Şimdi Rol
modelinin pivot
nesnesinde falan
ve filan
nitelikleri erişilebilir olacaktır.
Eğer pivot tablonuzun created_at
ve updated_at
zaman damgalarını otomatik olarak halletmesini istiyorsanız, ilişki tanımlamasında withTimestamps
metodunu kullanın:
return $this->belongsToMany('Rol')->withTimestamps();
Bir modelin pivot tablosundaki tüm kayıtları silmek için, detach
metodunu kullanabilirsiniz:
Bir Pivot Tablodaki Tüm Kayıtların Silinmesi
Uye::find(1)->roller()->detach();
Bu operasyonun roller
tablosundan kayıt silmediğine, sadece pivot tablodan sildiğine dikkat ediniz.
Eloquent tarafından döndürülen tüm çoklu sonuç kümeleri ya get
metodu aracılığıyla döndürülür veya bir ilişki bir Eloquent Collection
nesnesi döndürür. Bu nesne PHP'nin IteratorAggregate
arayüzünün bir uygulama biçimidir ve tıpkı bir dizide dolaşır gibi dolaşılabilinmektedir. Bunun yanında, bu nesne sonuç kümeleriyle çalışırken işe yarayan başka bir takım metodlara da sahiptir.
Örneğin biz contains
metodunu kullanarak bir sonuç kümesinin belli bir primer key içerip içermediğini tespit edebiliriz:
Bir Koleksiyonun Bir Key Taşıyıp Taşımadığının Yoklanması
$roller = Uye::find(1)->roller;
if ($roller->contains(2))
{
//
}
Koleksiyonlar aynı zamanda bir dizi ya da JSON'a dünüştürülebilmektedir:
$roller = Uye::find(1)->roller->toArray();
$roller = Uye::find(1)->roller->toJson();
Eğer bir koleksiyon bir string kalıbına çevrilirse JSON olarak döndürülecektir:
$roller = (string) Uye::find(1)->roller;
Eloquent koleksiyonları içerdikleri elemanları dolaşmak ve filtre etmekle ilgili bazı metodlara da sahiptir:
Koleksiyonlarda Tekrarlı İşlemler ve Süzmeler
$roller = $uye->roller->each(function($rol)
{
});
$roller = $uye->roller->filter(function($rol)
{
});
Her Bir Koleksiyon Nesnesine Bir Dönüş (Callback) Yapmak
$roller = Uye::find(1)->roller;
$roller->each(function($rol)
{
//
});
Bir Koleksiyonu Bir Değere Göre Sıralama
$roller = $roller->sortBy(function($rol)
{
return $rol->created_at;
});
Bazen de, kendi eklediğiniz metodları olan özel bir koleksiyon nesnesi döndürmek isteyebilirsiniz. Bunu, Eloquent modeliniz üzerinde newCollection
metodunu ezerek yapabilirsiniz:
Özel Bir Koleksiyon Tipinin Döndürülmesi
class Uye extends Eloquent {
public function newCollection(array $models = array())
{
return new CustomCollection($models);
}
}
Eloquent model niteliklerini alıp getirirken veya onları ayarlarken dönüşüm yapmak için uygun bir yol sağlar. Bir erişimci beyan etmek için modeliniz üzerinde sadece bir getFilanAttribute
metodu tanımlamak yeterlidir. Yalnız unutmamanız gereken şey, veritabanı sütunlarınızın isimleri yılan tarzı (küçük harfli kelimelerin boşluk olmaksızın alt tire ile birbirine bağlanması) olsa dahi, metodlarınızın deve tarzı (birinci kelimenin tümü küçük harf olmak ve sonraki kelimelerin ilk harfi büyük diğer hafleri küçük olmak üzere boşluk olmaksızın kelimelerin yanyana dizilmesi) olması gerektiğidir:
Bir Erişimci Tanımlanması
class Uye extends Eloquent {
public function getSoyAdiAttribute($value)
{
return ucfirst($value);
}
}
Yukarıdaki örnekte soy_adi
sütununun bir erişimcisi vardır. Niteliğin değerinin erişimciye geçildiğine dikkat ediniz.
Değiştiriciler de benzer şekilde deklare edilir:
Bir Değiştirici Tanımlanması
class Uye extends Eloquent {
public function setSoyAdiAttribute($value)
{
$this->attributes['soy_adi'] = strtolower($value);
}
}
Ön tanımlı olarak, Eloquent will convert the created_at
, updated_at
, and deleted_at
columns to instances of Carbon, olgularına çevirecektir. Carbon çeşitli yardımcı metodlar sağlar ve PHP'nin DateTime
sınıfını genişletir.
Siz hangi alanların otomatik olarak değiştirileceğini isteğinize göre ayarlayabilirsiniz, hatta modeldeki getDates
metodunu ezmek suretiyle bu motasyonu tamamen devre dışı bırakabilirsiniz:
public function getDates()
{
return array('created_at');
}
Bir sütun bir tarih olarak kabul edildiğinde, bunun değerini bir UNIX timetamp, date string (Y-m-d
), date-time string ve tabii ki bir DateTime
/ Carbon
olgusuna ayarlayabilirsiniz.
Tarih değiştiricilerini tümden devre dışı bırakmak için getDates
metodunda boş bir dizi döndürünüz:
public function getDates()
{
return array();
}
Eloquent modelleri bazı olayları tetikleyerek, modelin yaşam döngüsündeki çeşitli noktalarda müdahale etmenize imkan verir. Bu amaçla şu metodlar kullanılmaktadır: creating
, created
, updating
, updated
, saving
, saved
, deleting
, deleted
. Eğer creating
, updating
veya saving
olaylarından false
döndürülürse, eylem iptal edilecektir:
Saklama Operasyonlarının Olaylar Aracığıyla İptal Edilmesi
Uye::creating(function($uye)
{
if ( ! $uye->isValid()) return false;
});
Eloquent modelleri bunun dışında static bir boot
metodu içermekte olup, olay bağlamanızı kayıt etmeniz için uygun bir yerdir.
Bir Model Boot Metodunun Ayarlanması
class Uye extends Eloquent {
public static function boot()
{
parent::boot();
// Olay bağlamayı ayarla...
}
}
Model olaylarının işlenmesini pekiştirmek için, bir model gözlemcisi kaydı yapabilirsiniz. Bir gözlemci sınıfında çeşitli model olaylarına tekabül eden metodlar bulunabilir. Örneğin bir gözlemcide, diğer model olay isimlerine ek olarak creating
, updating
, saving
metodları olabilir.
Yani, bir model gözlemcisi şöyle olabilir:
class UyeGozlemcisi {
public function saving($model)
{
//
}
public function saved($model)
{
//
}
}
Modelinizde observe
metodunu kullanarak bir gözlemci olgusu kaydı yapabilirsiniz:
Uye::observe(new UyeGozlemcisi);
JSON APIler oluşturulurken, çoğu defa modellerinizi ve ilişkilerini dizilere veya JSON'a çevirmeniz gerekecektir. Bu yüzden Eloquent bunları yapacak metodlar içermektedir. Bir modeli ve onun yüklenen ilişkilerini bir diziye çevirmek için toArray
metodunu kullanabilirsiniz:
Bir Modelin Bir Diziye Çevrilmesi
$uye = Uye::with('roller')->first();
return $uye->toArray();
Modellerin koleksiyonlarının da bütün olarak dizilere dönüştürülebildiğini unutmayın:
return Uye::all()->toArray();
Bir Modeli JSON'a çevirmek için, toJson
metodunu kullanabilirsiniz:
Bir Modelin JSON'a Çevrilmesi
return Uye::find(1)->toJson();
Bir model veya koleksiyon bir string kalıbına sokulduğu takdirde, JSON'a çevrileceğine dikkat ediniz. Yani Elequent nesnelerini direkt olarak uygulamanızın rotalarından döndürebilirsiniz!
Bir Modelin Bir Rotadan Döndürülmesi
Route::get('uyeler', function()
{
return Uye:all();
});
Bazen bazı nitelikleri (örneğin şifreleri) modelinizin dizi veya JSON biçimlerinden hariç tutmak isteyebilirsiniz. Bunu yapmak için modelinize bir hidden
özelliği ekleyiniz:
Niteliklerin Dizi veya JSON'a Çevrilmekten Saklanması
class Uye extends Eloquent {
protected $hidden = array('parola');
}
Alternatif olarak, beyaz bir liste tanımlamak için visible
özelliğini kullanabilirsiniz:
protected $visible = array('adi', 'soy_adi');