Merhaba arkadaşlar, bugün Laravel'de sıkça ihtiyaç duyduğumuz ama ilk bakışta karmaşık gelebilen bir konuyu, polymorphic ilişkileri, pratik bir örnekle anlatacağım. Projelerimde Post, Video, Ürün gibi farklı modellere yorum yapabilme ihtiyacı doğduğunda, her biri için ayrı yorum tabloları oluşturmak yerine, tek bir genel yorum sistemi kurmak beni çok rahatlattı. İşte bu esnekliği sağlayan yöntem!
Neden Ayrı Tablolar Yerine Polymorphic İlişki?
Diyelim ki bir blog ve bir video portalı yapıyorsunuz. Klasik yaklaşımda `post_comments` ve `video_comments` diye iki ayrı tablonuz olur. Her yeni bir yorumlanabilir içerik türü (mesela `products`) eklediğinizde yeni bir `product_comments` tablosu ve modeli oluşturmanız gerekir. Bu, kod tekrarına ve yönetim zorluğuna yol açar. Polymorphic ilişki ile tek bir `comments` tablosu, hepsini halleder!
Veritabanı Migrasyonunu Hazırlama
İlk adım, yorumlarımızı tutacak tabloyu oluşturalım. Bu tabloda sihirli iki sütun var: `commentable_id` ve `commentable_type`.
Gördüğünüz gibi, `commentable_type` sütunu ilişki kurulacak modelin sınıf adını (ör. `App\Models\Post`), `commentable_id` ise o modeldeki kaydın ID'sini tutacak. Bu ikili, yorumun hangi "şeye" ait olduğunu belirler.
Modellerde İlişkiyi Tanımlama
Şimdi sıra, modellerimizde bu ilişkiyi kurmaya. Önce ana modelimiz olan `Comment` modelini hazırlayalım.
`commentable` metodundaki `morphTo()`, bu yorumun `Post`, `Video` vs. gibi diğer modellere dinamik bağlanmasını sağlar.
Şimdi de yorumlanabilir modellerimize (`Post` ve `Video`) gerekli ilişkiyi ekleyelim.
Her iki modelde de aynı `morphMany` ilişkisini kullanıyoruz. Artık bir `Post` veya `Video` kaydı, birçok `Comment`'e sahip olabilir.
Pratikte Kullanım Örnekleri
İlişkiler hazır, şimdi bunları nasıl kullanacağımıza bakalım.
Bir gönderiye yorum eklemek:
Bir videonun tüm yorumlarını çekmek:
Herhangi bir yorumun hangi modele ait olduğunu bulmak: Bu, sistemin en güzel yanı!
Sonuç ve Düşünceler
Bu yapıyı kurduktan sonra, `Product`, `Article` gibi yeni modeller eklemek inanılmaz basit. Sadece yeni modele bir `morphMany` ilişkisi eklemeniz yeterli. Kod tekrarı sıfır, merkezi yönetim mükemmel.
Siz Laravel'de polymorphic ilişkileri başka hangi senaryolarda kullanıyorsunuz? Mesela "beğeni" sistemi, "dosya ekleme" veya "etiketleme" için de kullanan oldu mu? Yorumlarda deneyimlerinizi paylaşın, hep birlikte öğrenelim!
Diyelim ki bir blog ve bir video portalı yapıyorsunuz. Klasik yaklaşımda `post_comments` ve `video_comments` diye iki ayrı tablonuz olur. Her yeni bir yorumlanabilir içerik türü (mesela `products`) eklediğinizde yeni bir `product_comments` tablosu ve modeli oluşturmanız gerekir. Bu, kod tekrarına ve yönetim zorluğuna yol açar. Polymorphic ilişki ile tek bir `comments` tablosu, hepsini halleder!
İlk adım, yorumlarımızı tutacak tabloyu oluşturalım. Bu tabloda sihirli iki sütun var: `commentable_id` ve `commentable_type`.
PHP:
// database/migrations/xxxx_xx_xx_xxxxxx_create_comments_table.php
public function up()
{
Schema::create('comments', function (Blueprint $table) {
$table->id();
$table->text('body');
$table->foreignId('user_id')->constrained()->onDelete('cascade');
// Polymorphic ilişki sütunları
$table->unsignedBigInteger('commentable_id');
$table->string('commentable_type');
$table->timestamps();
});
}
Gördüğünüz gibi, `commentable_type` sütunu ilişki kurulacak modelin sınıf adını (ör. `App\Models\Post`), `commentable_id` ise o modeldeki kaydın ID'sini tutacak. Bu ikili, yorumun hangi "şeye" ait olduğunu belirler.
Şimdi sıra, modellerimizde bu ilişkiyi kurmaya. Önce ana modelimiz olan `Comment` modelini hazırlayalım.
PHP:
// app/Models/Comment.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphTo;
class Comment extends Model
{
protected $fillable = ['body', 'user_id'];
public function commentable(): MorphTo
{
return $this->morphTo();
}
public function user()
{
return $this->belongsTo(User::class);
}
}
`commentable` metodundaki `morphTo()`, bu yorumun `Post`, `Video` vs. gibi diğer modellere dinamik bağlanmasını sağlar.
Şimdi de yorumlanabilir modellerimize (`Post` ve `Video`) gerekli ilişkiyi ekleyelim.
PHP:
// app/Models/Post.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphMany;
class Post extends Model
{
public function comments(): MorphMany
{
return $this->morphMany(Comment::class, 'commentable');
}
}
PHP:
// app/Models/Video.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphMany;
class Video extends Model
{
public function comments(): MorphMany
{
return $this->morphMany(Comment::class, 'commentable');
}
}
Her iki modelde de aynı `morphMany` ilişkisini kullanıyoruz. Artık bir `Post` veya `Video` kaydı, birçok `Comment`'e sahip olabilir.
İlişkiler hazır, şimdi bunları nasıl kullanacağımıza bakalım.
Bir gönderiye yorum eklemek:
PHP:
$post = Post::find(1);
$comment = $post->comments()->create([
'body' => 'Harika bir yazı olmuş!',
'user_id' => auth()->id()
]);
// Laravel otomatik olarak commentable_id=1 ve commentable_type='App\Models\Post' dolduracak.
Bir videonun tüm yorumlarını çekmek:
PHP:
$video = Video::with('comments.user')->find(5);
foreach($video->comments as $comment) {
echo $comment->body . " - Yazan: " . $comment->user->name;
}
Herhangi bir yorumun hangi modele ait olduğunu bulmak: Bu, sistemin en güzel yanı!
PHP:
$comment = Comment::find(10);
$commentableItem = $comment->commentable; // Bu bir Post veya Video model örneği döndürür!
if($commentableItem instanceof Post) {
echo "Bu yorum bir blog yazısına ait: " . $commentableItem->title;
}
Bu yapıyı kurduktan sonra, `Product`, `Article` gibi yeni modeller eklemek inanılmaz basit. Sadece yeni modele bir `morphMany` ilişkisi eklemeniz yeterli. Kod tekrarı sıfır, merkezi yönetim mükemmel.
Siz Laravel'de polymorphic ilişkileri başka hangi senaryolarda kullanıyorsunuz? Mesela "beğeni" sistemi, "dosya ekleme" veya "etiketleme" için de kullanan oldu mu? Yorumlarda deneyimlerinizi paylaşın, hep birlikte öğrenelim!