Skip to main content

Hati hati menggunakan Eager Load dan appends pada Eloquent

ยท 2 min read

Adakala kita melakukan Eager Load pada Eloquent untuk mengatisipasi n+1 query. Dan juga properti appends untuk menambahkan atribut tanpa perlu memanggil atribut secara manual.

Tapi, perlu diperhatikan kembali jika menggunakan kedua hal tersebut secara bersamaan terhadap kedua model yang saling berelasi. Karena dapat membuat sebuah program looping yang tidak habis-nya (Stactoverflow) dan server akan stuck serta bisa mengakibatkan GTO (Gateway Timeout) jika max_execution_time tercapai.

Contoh kita mempunyai model Author dan Article. Author mempunyai relasi dengan Article, begitu sebaliknya.

Pada model Author kita mendeklarasikan sebuah relasi ke model Article menggunakan method hasOne() serta Eager Load ke relasi article tersebut.

protected $with = [
'article',
];

public function article()
{
return $this->hasOne(Article::class, 'id', 'article_id');
}

Dan pada model Article kita mendeklarasikan sebuah relasi juga ke model Author kembali.

public function author()
{
return $this->hasOne(Author::class, 'article_id', 'id');
}

Setelah kedua relasi dideklarasikan, maka kita coba untuk menampilkan data list Author beserta Article yang berelasi dengannya.

public function index()
{
$data = Author::all();

return $data;
}

Mimpi buruk pun datang ketika mengakses kembali halaman tersebut.

Alt text

Karena pada Article melakukan appends yang berelasi ke Author dan di Author melakukan Eager Load Article. Dan berlangsung terus menerus sampai GTO (Gateway Timeout).

article -> author_name (appends) -> author -> article (eager load) -> author_name (appends) -> article (eager load) -> author -> ...

Ada 2 solusi yang saya dapatkan untuk mengatasi kasus seperti diatas adalah.

  1. Dengan menggunakan makeHidden(), yakni dengan men-disable sementara salah satu properti appends agar tidak melakukan kontak dengan Author yang melakukan Eager Load terhadap Article.
public function index()
{
$data = Article::get()->makeHidden('author_name');

return $data;
}

โš ๏ธ Dampak dari hal tersebut adalah, kita tidak bisa melihat data dari author_name di list Article.

Alt text

  1. Dengan menghilangkan Eager Load article pada model Author. Sehingga data dari author_name dapat tampil pada list Article.

Alt text

โš ๏ธ Dampaknya adalah kita harus melakukan Eager Load secara manual pada model Author ke model Article dengan menggunakan method with() untuk menghindarkan terjadinya n+1 query.

Untuk mengatasi GTO penggunaan Eager Load dan appends ada 2 solusi yang didapatkan.