Laravel Eloquent Many-to-Many ilişkisi

Merhabalar bu blog yazısında sizlere Laravel Eloquent’ta çoka-çok ilişkinin nasıl kurulduğu konusunu açıklayacağım ve örnekler yapacağım.

Laravel Eloquent Many-to-Many ilişkisi
Laravel çoka-çok ilişki

Merhabalar bu blog yazısında sizlere Laravel Eloquent’ta çoka-çok ilişkinin nasıl kurulduğu konusunu açıklayacağım ve örnekler yapacağım.

Oluşturulacak senaryo

 

Senaryomuz kullanıcılar ve rolleri üzerine olacak. Bildiğiniz gibi bir kullanıcının birden fazla rolü olabilir ve bir rolün de birden fazla kullanıcısı olabilir. Bu ilişkiyi sağlamak için bir ara tabloya ihtiyaç duyarız bu tabloya “pivot” adı verilir. Bizim senaryomuzda User ve Role  tabloları olacak. Pivot tablo olarak da user_roles tablosu olacak.

Pivot tablomuz içerisinde user_id ve role_id’yi barındıracak. Bu sayede çoka-çok ilişkimizi oluşturmuş olacağız.

Migration’ların oluşturulması

Halihazırda Laravel’in içerisinde beraber gelen User modelimiz ve migration’umuzu kullanıcı işlemlerimiz için kullanacağız.
Bunun yanı sıra roles tablosu için aşağıdaki migration ayarlamalarını yapıyoruz modelimizin de beraberinde oluşmasını istiyorsak direkt olarak make:migration roles -m  komutunu kullanabiliriz.

Schema::create('roles', function (Blueprint $table) {
            $table->increments("id");
            $table->string('name');
            $table->timestamps();
        });
    }

Bu işlemin ardından aynı şekilde pivot tablomuz için bir migration oluşturuyoruz ancak bu migration’ın modeli olmasına gerek yok.

  Schema::create('role_user',function(Blueprint $table){
            $table->increments('id');
            $table->bigInteger('user_id');
            $table->bigInteger('role_id');
            $table->timestamps();
        });
    }

 

İlişkilerin oluşturulması

İlişkileri oluşturmak için belongsToMany() metodunu kullanacağız. Bu metot bize çoka çok ilişkiyi oluşturacak.
Metot bize erişilmek istenilen tablomuzun modelinden bir örnek istiyor. Bu örnek zorunlu ama diğer parametreler zorunlu değil. Diğer parametreleri kendi otomatik algoritması ile tahmin ediyor bunu anlatmadan önce bizden hangi parametreleri beklediğine bir göz atalım:

return $this->belongsToMany(ilişkilenecek_model, pivot_tablo_adi, su_anki_modelin_pivot_tablodaki_yabancı_anahtarı, ilişkinin_olduğu_tablonun_pivot_tablodaki_yabancı_anahtarı)

Yukarıda görüldüğü gibi parametrelere ihtiyaç duyan bir metot , ancak zorunlu parametre sadece en baştaki ilişkilenecek_model kısmı onun haricindeki diğer alanlar zorunlu değil. Peki nasıl bağlantıyı kuruyor diye soracak olursanız.

Çoka çok ilişkide bir standart olduğu için Laravel iki modelin adını alfabetik sıra ile ve aralarına “_” koyarak birleştirir örneğimizde olduğu gibi “role_user” olarak belirler  yani sinif ve ogrenci adında iki modelimiz olsaydı ogrenci_sinif olarak pivot tablo ismini belirleyip bağlantıyı kuracaktı. Diğer foreign_key alanları da aynı şekilde “modelismi_id” şeklinde belirlenecekti. Eğer bu alanlar da bir farklılık var ise direkt olarak parametreleri el ile girmek de fayda var.

User modeli için rol ilişkisi

// Many-to-many metot kullanımı
    public function roles(){

        return $this->belongsToMany(\App\Models\Role::class);
        //Veya
        return $this->belongsToMany(\App\Models\Role::class,"role_user","user_id","role_id");

    }

Role modeli için rol ilişkisi

 public function users(){
        return $this->belongsToMany(\App\Models\User::class);
 }

 

İlişkili verileri çekme

Bir(1) id’li üyenin yetkilerini çekmek istediğimiz zaman aşağıdaki kod bloğunu kullanabiliriz.
Buradaki pluck() metodu bütün bir model bilgisinden ziyade sadece belirli bir alanı çekmek istediğimizde kullanılır. Biz de sadece name alanını çekmek istediğimizi belirttik.

 $user = User::find(1);

 dd($user->roles->pluck('name'));

Çıktı:

^ Illuminate\Support\Collection {#267 ▼
  #items: array:4 [▼
    0 => "Super-Admin"
    1 => "Admin"
    2 => "Editör"
  ]
  #escapeWhenCastingToString: false

Attach , detach, sync ve metotları

Laravel Eloquent’ta çoka-çok ilişki kurulurken pivot tabloya ilişkili olunan tablodaki istediğimiz kayıtları ekleyip silmek isteyebiliriz.

Bizim senaryomuzda kullanıcılar ve roller olduğu için senaryomuz doğrultusunda bir üyeye rol veya roller ekleyeceğiz. Bunun tam tersi olarak da role üye ekleyeceğiz.

Attach metodu

Attach metodu direkt tek değer veya dizi alabilmektedir.Pivot tablo içerisine çağrıldığı kayıt için kayıt yapar.

Aldığı değer birincil anahtar olmak  zorundadır. Örnek kullanımı:

Aşağıdaki kod 2 numaralı id değerine sahip kayıta istenilen id numaralarında rolleri ekler.

// //İkinci id'li user'a admin ve super-admin rollerini atar tek bir kayıt atamak isterken dizi
    // şeklinde yollamamıza gerek yok
    User::find(2)->roles()->attach([1,2]);

User’ımıza ait rolleri bir dizi şeklinde listelemek istersek aşağıdaki kod bloğunu kullanabiliriz.

 // Buradaki pluck metotu istediğimiz alanları getir sadece
 // Ve bizler collection sınıfından dönen değeri bir dizi şeklinde almak istiyorsak toArray() 
 // metodunu kullanırız.
 dd(User::find(2)->roles()->pluck('name')->toArray());

Çıktı:

array:2 [▼
  0 => "Super-Admin"
  1 => "Admin"
]

Deatch Metodu

 

Bu metot tahmin de edeceğiniz gibi pivot tablodan çağrıldığı model örneğinin istenilen kayıtlarını çıkartır.
Kullanımı:
Eğer parametre almaz ise direkt ilişkili tüm kayıtları siler, kullanırken dikkatli olalım ????

Bunun haricinde attach() metodunda olduğu gibi direkt çıkartılmak istenilen id bilgileri verilir .

 //    Tüm ilişkili kayıtları siler.
    $user = User::find(2);
    $user->roles()->detach();
    // İstenilen spesifik kayıtları siler.
    $user->roles()->detach([1, 2]);

Sync Metodu

Bu metot adından da anlaşılabileceği gibi senkronize mantığı ile ilerler. İlgili modelin ilişkili olduğu tüm kayıtları siler ve bizim verdiğimiz değerleri tabloya ekler.

Örnek vermek gerekirse halihazırda bir üyenin super-admin ve admin rolü olduğunu düşünelim , biz gelip sync() metodunu kullanıp içerisine sadece editör rolünün id numarasını verirsek gidip pivot tabloya sadece Edidör rolünün id’sini ekleyecektir.

Kullanım örneği:

//    Tüm ilişkili kayıtları siler ve bizim verdiğimiz yeni değerleri ekler.
    $user = User::find(2);
    $user->roles()->sync([1,2]);

 

Laravelde çoka çok ilişkiyi ve diğer ilişki türlerini anlattığım videolarımı Youtube kanalımdan izleyebilirsiniz.