Poznajemy entity managera po raz pierwszy. Kontynuacja poprzednich lekcji o Symfony. Do dzieła.
Ok, przypomnijmy sobie tę metodę:
#[Route('/micro_post/{id}', name: 'app_micro_post_show')]
public function showOne(int $id, MicroPostRepository $repository): Response
{
return $this->render('micro_post/single.html.twig', [
'post' => $repository->find($id),
]);
}
Wstrzykujemy repozytorium i używamy find, aby dostać entity. Teraz wersja z auto-wiring (odpowiednik route-model binding z Laravela):
#[Route('/micro_post/{post}', name: 'app_micro_post_show')]
public function showOne(MicroPost $post): Response
{
return $this->render('micro_post/single.html.twig', ['post' => $post]);
}
Ok, teraz zaimportujemy sobie EntityManagera:
use Doctrine\ORM\EntityManagerInterface;
I użyjemy go w podobny sposób co metoda pierwsza:
#[Route('/micro_post_entity/{id}', name: 'app_micro_post_show_entity')]
public function showOneEntity(EntityManagerInterface $entityManager, int $id): Response
{
$post = $entityManager->getRepository(MicroPost::class)->find($id);
return $this->render('micro_post/single.html.twig', ['post' => $post]);
}
Ktoś może zapytać po co to jest, skoro i tak pobiera repozytorium. Cóż, w tym przypadku tak. Natomiast w Symfony jest wzorzec entity-repository i pewne rzeczy są oddzielone:
- Entity to taki jakby model z Laravela
- Repository to coś co służy zwracaniu pojedynczych entities oraz kolekcji
- EntityManager to coś, co zapisuje do bazy danych/usuwa z bazy danych
- Repository ma ograniczoną ilość query (znajdź jednego, przynieś wszystkie, znajdź jednego po kolumnie równej x, przynieś wszystkie po kolumnie równej x)
- Repository ma metodę createQueryBuilder służącą do tworzenia query buildera w sposób podobny do Laravel local query scopes
Z uwagi na tę architekturę myślę, że warto było wprowadzić entity managera tak szybko, jak to możliwe.
Przykład z dokumentacji Symfony:
// src/Controller/ProductController.php
namespace App\Controller;
use App\Entity\Product;
use App\Repository\ProductRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
// ...
class ProductController extends AbstractController
{
#[Route('/product/edit/{id}', name: 'product_edit')]
public function update(EntityManagerInterface $entityManager, int $id): Response
{
$product = $entityManager->getRepository(Product::class)->find($id);
if (!$product) {
throw $this->createNotFoundException(
'No product found for id '.$id
);
}
$product->setName('New product name!');
$entityManager->flush();
return $this->redirectToRoute('product_show', [
'id' => $product->getId()
]);
}
}
Schemat działania:
- Wstrzykujemy entity manager
- EntityManager pobiera repozytorium klasy Product, repozytorium znajduje entity product o podanym id
- To entity ma metodę setName, która jest użyta
- EntityManager wykonuje flush, co sprawia, że w bazie danych zmiany zostaną zapisane
Więcej o tym niebawem, ale myślę, że warto to konceptualnie sobie rozłożyć, bo jest inaczej niż w Laravelu.