Çoklu kiracılık (Multi-tenancy) yaklaşımı, genellikle kiracıya özel rollerin nerede tutulması gerektiği sorusunu gündeme getirir.
Multi-Tenant Starter’ı inşa etmeye başladığımda, bir TeamUser pivot tablosuyla başlamadım. Bunun yerine, Spatie’nin kendi takım özelliğini kullandım, çünkü bu özellik zaten laravel-permission paketinde mevcut ve başlangıç noktası olarak mantıklı görünüyordu.
Bu yaklaşımı daha önce Filament Mastery’de yazmıştım: Spatie’nin konfigürasyonunda teams => true aktif hale getirilerek, rol atamalarının setPermissionsTeamId() ile bir kiracı middleware’ı içinde sınırlanması gibi işlemler.
Ancak bu yöntem beklediğim gibi çalışmadı ve bunun nedeni daha ilginçti.
Başlangıç Noktası
Başlangıç Noktası
Spatie’nin laravel-permission paketi, takımlar için yerleşik destek sunmaktadır. Aktif hale getirilirse, model_has_roles tablosundaki her satır için team_id sütunu eklenir. Bir rol ataması, global yerine bir takıma özel hale gelir ki bu, çoklu kiracılık gereksinimleri için doğru bir başlangıç noktasıdır.
Bu nedenle, ben de buradan yola çıktım. Bir User, bir Team ile ilişkilidir ve bu takım içindeki rolü Spatie rolü olarak team_id ile saklanır.
Sorunun Ortaya Çıktığı Nokta
Sorunun Ortaya Çıktığı Nokta
Multi-Tenant Starter’da bir kullanıcı, herhangi bir takıma ait olmadan Member uygulama rolünü (üye paneline erişim sağlayan rol) alabilir. Birisi davet edilir, kayıt olur veya üye olur ve takıma katılmadan önce üye paneline ulaşır.
Spatie’nin takım modu aktif olduğunda, model_has_roles tablosundaki her satır için bir team_id gereklidir. Spatie’nin kendi migration dosyasına baktığınızda, team_id bu tablonun bileşik birincil anahtarı parçası haline gelir:
$table->primary(
[$columnNames['team_foreign_key'], $pivotRole, $columnNames['model_morph_key'], 'model_type'], 'model_has_roles_role_model_type_primary'
);
Bileşik birincil anahtar, sütunlardan herhangi birinin NULL değerini içermesine izin vermez; bu, standart bir SQL kısıtlamasıdır ve Spatie tarafından belirlenmemiştir. İşte bu nedenle, sütunun var olabilmesi için bir varsayılan değere ihtiyacı vardır:
$table->unsignedBigInteger($columnNames['team_foreign_key'])->default('1');
Bunu yapmadığınız takdirde, bir team_id bilinmeden yapılan herhangi bir rol ataması veritabanı seviyesinde başarısız olur. Bununla birlikte, varsayılan değer ile ekleme başarılı olur; fakat kullanıcıya ait bir takım bilinmeden atanan rol, sessizce 1 ID’li takıma eklenir. Bu, bir hata değil, bir istisna değil; sadece kullanıcının gerçek anlamda ilişkisi olmadığı bir takıma yönelik rol atanmasıdır. Bu durum, bir hata durumundan daha kötü: hiçbir şey çökmez, uyarı yapmaz ve veriler yanlış kalır, birisi kullanıcının katılmadığı bir takımda izinleri olduğunu fark edene kadar.
Ben de bu durumu, takım ID’sini 1 ile özel bir hale getirmeyi veya Spatie’nin migration dosyasını değiştirerek team_id‘nin NULL olabilmesini sağlamayı istemedim; bu, birincil anahtarı tamamen kaldırmadan ya da yerine benzersiz bir indeks koymadan izin vermez. Bu nedenle, takım modundan tamamen geri adım attım.
Bunun Yerine Ne Yaptım?
Bunun Yerine Ne Yaptım?
Tamamı için makale, Filament Mastery‘de ücretsiz üyelere sunulmuştur.
Kaynak: Orijinal Makale


