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.
}
}