Laravel'de Eloquent ORM İlişkileri: Junior'a Yönelik Kapsamlı Rehber
Published: 2024-06-10 08:28:52

Laravel'de Eloquent ORM (Object-Relational Mapping), veritabanı ile çalışmayı oldukça kolay ve etkili hale getirir. Eloquent ORM, veritabanı tablolarımızı ve bu tablolar arasındaki ilişkileri kolayca tanımlamamıza ve yönetmemize olanak sağlar. Bu makalede, Eloquent ORM ilişkilerini ayrıntılı bir şekilde ele alacağız. "BelongsToMany", "HasMany" gibi ilişkilerin ne olduğunu, hangi durumlarda kullanıldığını ve nasıl kullanıldığını örnek kodlarla açıklayacağız.

### Eloquent ORM İlişki Türleri

#### 1. One-to-One (Bire Bir) İlişkisi

Bir bire bir ilişkisi, bir tablodaki bir kaydın başka bir tablodaki bir kayda bağlanmasıdır. Örneğin, bir kullanıcının yalnızca bir profili olabilir.

##### Örnek:
- Bir `User` ve `Profile` tabloları olduğunu varsayalım. Her kullanıcının yalnızca bir profili vardır.

**User Model:**
```php
class User extends Model
{
    public function profile()
    {
        return $this->hasOne(Profile::class);
    }
}
```

**Profile Model:**
```php
class Profile extends Model
{
    public function user()
    {
        return $this->belongsTo(User::class);
    }
}
```

Bu ilişkide, `users` tablosu `profiles` tablosuyla bire bir ilişkilidir. `User` modelinde `hasOne(Profile::class)` yöntemi kullanılır çünkü bir kullanıcı sadece bir profile sahip olabilir. `Profile` modelinde `belongsTo(User::class)` yöntemi kullanılır çünkü bir profil bir kullanıcıya aittir.

#### 2. One-to-Many (Bire Çok) İlişkisi

Bir bire çok ilişkisi, bir tablodaki bir kaydın başka bir tablodaki birden fazla kayda bağlanmasıdır. Örneğin, bir kullanıcının birden fazla blog gönderisi olabilir.

##### Örnek:
- Bir `User` ve `Post` tabloları olduğunu varsayalım. Her kullanıcının birden fazla blog gönderisi olabilir.

**User Model:**
```php
class User extends Model
{
    public function posts()
    {
        return $this->hasMany(Post::class);
    }
}
```

**Post Model:**
```php
class Post extends Model
{
    public function user()
    {
        return $this->belongsTo(User::class);
    }
}
```

Bu ilişkide, `users` tablosu `posts` tablosuyla bire çok ilişkilidir. `User` modelinde `hasMany(Post::class)` yöntemi kullanılır çünkü bir kullanıcı birçok blog gönderisine sahip olabilir. `Post` modelinde `belongsTo(User::class)` yöntemi kullanılır çünkü bir blog gönderisi bir kullanıcıya aittir.

#### 3. Many-to-Many (Çoktan Çoğa) İlişkisi

Bir çoktan çoğa ilişkisi, bir tablodaki birçok kaydın başka bir tablodaki birçok kayda bağlanmasıdır. Örneğin, bir öğrencinin birçok kursu olabilir ve bir kursun birçok öğrencisi olabilir.

##### Örnek:
- Bir `Student` ve `Course` tabloları olduğunu varsayalım. Her öğrencinin birçok kursu olabilir ve her kursun birçok öğrencisi olabilir. Bu tür ilişkilerde genellikle ara bir tablo (pivot table) kullanılır.

**Student Model:**
```php
class Student extends Model
{
    public function courses()
    {
        return $this->belongsToMany(Course::class);
    }
}
```

**Course Model:**
```php
class Course extends Model
{
    public function students()
    {
        return $this->belongsToMany(Student::class);
    }
}
```

Ara tablo genellikle iki tablonun isimlerinin birleşiminden oluşur, örneğin `course_student`. Bu tablo, `student_id` ve `course_id` sütunlarını içerir.

**Migration Örneği:**
```php
Schema::create('course_student', function (Blueprint $table) {
    $table->id();
    $table->foreignId('student_id')->constrained()->onDelete('cascade');
    $table->foreignId('course_id')->constrained()->onDelete('cascade');
    $table->timestamps();
});
```

#### 4. Has Many Through (Dolaylı Bire Çok) İlişkisi

Dolaylı bire çok ilişkisi, bir modelin, bir başka model üzerinden ilişkili olduğu birçok modelin varlığı durumudur. Örneğin, bir ülkenin birçok şehri ve şehirlerin de birçok kullanıcısı olabilir.

##### Örnek:
- Bir `Country`, `City` ve `User` tabloları olduğunu varsayalım. Her ülkenin birçok şehri ve her şehrin birçok kullanıcısı vardır.

**Country Model:**
```php
class Country extends Model
{
    public function users()
    {
        return $this->hasManyThrough(User::class, City::class);
    }
}
```

**City Model:**
```php
class City extends Model
{
    public function country()
    {
        return $this->belongsTo(Country::class);
    }

    public function users()
    {
        return $this->hasMany(User::class);
    }
}
```

**User Model:**
```php
class User extends Model
{
    public function city()
    {
        return $this->belongsTo(City::class);
    }
}
```

Bu ilişkide, `countries` tablosu `users` tablosuna `cities` tablosu üzerinden dolaylı olarak bağlıdır.

#### 5. Polymorphic Relations (Çok Biçimli İlişkiler)

Çok biçimli ilişkiler, farklı modellerin aynı ilişkisel yapıyı paylaşmasına izin verir. Örneğin, hem `Post` hem de `Video` modellerinin yorumları olabilir.

##### Örnek:
- Bir `Post`, `Video` ve `Comment` tabloları olduğunu varsayalım. Hem gönderilerin hem de videoların yorumları olabilir.

**Post Model:**
```php
class Post extends Model
{
    public function comments()
    {
        return $this->morphMany(Comment::class, 'commentable');
    }
}
```

**Video Model:**
```php
class Video extends Model
{
    public function comments()
    {
        return $this->morphMany(Comment::class, 'commentable');
    }
}
```

**Comment Model:**
```php
class Comment extends Model
{
    public function commentable()
    {
        return $this->morphTo();
    }
}
```

`comments` tablosu, `commentable_id` ve `commentable_type` sütunlarını içerir. Bu sütunlar, hangi modelin yorumu olduğunu belirtir.

### Özet

- **`hasOne`**: Bir modelin başka bir modelle bire bir ilişkili olduğunu belirtir.
- **`belongsTo`**: Bir modelin başka bir modelin bir parçası olduğunu belirtir.
- **`hasMany`**: Bir modelin başka bir modelle bire çok ilişkili olduğunu belirtir.
- **`belongsToMany`**: Bir modelin başka bir modelle çoktan çoğa ilişkili olduğunu belirtir.

### Kullanım Senaryoları

- `hasOne`: Bir kullanıcının yalnızca bir profili olduğunda.
- `belongsTo`: Bir profilin yalnızca bir kullanıcısı olduğunda.
- `hasMany`: Bir kullanıcının birden fazla blog gönderisi olduğunda.
- `belongsToMany`: Bir öğrencinin birçok kursu ve bir kursun birçok öğrencisi olduğunda.