Relationship Methods vs. Dynamic Properties

Jakie są różnicę między metodą a dynamicznym atrybutem. Który jest lepszy? Oczywiście jak zawsze to zależy 🙂

use App\Models\User;
 
$user = User::find(1);
 
#Relationship Methods (RM)
foreach ($user->posts()->get() as $post) {
    // ...
}

vs

#Dynamic Properties (DP)
foreach ($user->posts as $post) {
    // ...
}

Pierwszy sposób (RM) ma wiele wad. Pierwszą z nich jest lazy loading. Czyli N+1 query problem i jeżeli użyjemy $user->posts()->get() 2 razy w ciągu jednego request’u, zostaną zrobione 2 takie same zapytanie do bazy danych.

Drugi sposób (DP). Używa Eager Loading, więc problem N+1 i powtarzających się zapytań zostaje rozwiązany. Czy jest on idealny? Oczywiście nie.
Laravel zapisuje dane z bazy danych w atrybucie statycznym. Statyczne atrybutu są zapisane do klasy nie obiektu.

Pierwszy problem, każde nowe stworzenie obiektu już będzie posiadać te dane.

Drugi problem jeżeli dla walidacji użyjemy (DP). I zwrócimy model bez żadnych limitów w kontrolerze (np. API resources), statyczne atrybuty zostaną zwrócone do API.

User Controller extends Controller 
{
  public function addEmail(User $user, string $email): array
  {
    if (in_array($email, $user->emails, true) {
      throw new Exception('Email already assigned');
    }

    return $user; //do api zostanie dodany atrybut emails, mimo że to nie było naszym celem.
  }
}
Scroll to Top