Základy a pravidla
Kolekce jsou základním stavebním kamenem pro vytváření API a datagridů. Definují se v adresáři app/Recipe
, pomocí tzv.
recipes (receptů). Každý recipe musí podědit třídu CollectionRecipe
a musí implementovat metody source
a key
.
- Pomocí metody
source
se definuje, která entita (DB tabulka) bude zdrojem dat. - Pomocí metody
key
se definuje API endpoint, přes který bude možné s daty pracovat.
Vytvoření kolekce
class UserRecipe extends CollectionRecipe
{
// Definice zdroje dat - entita (reprezentace DB tabulky)
public function source(): string
{
return User::class;
}
// Definice API endpointu
public function key(): string
{
return 'user';
}
}
Díky této krátké konfiguraci se vám automaticky vygeneruje datagrid a API pro entitu User
.
Vygenerovaný datagrid
V datagridu se zobrazí veškeré sloupce, které jsou definovány v přiřazené entitě - toto lze samozřejmě kompletně uzpůsobit pomocí pár řádků kódu - na podrobnou konfiguraci kolekcí se podíváme hned v dalších kapitolách.
Vygenerované REST API (CRUD)
Také se automaticky vygeneruje REST API pro všechny CRUD metody (Create, Read, Update, Delete a ReadAll). Příklady použití těchto metod naleznete v sekci Collections v REST API dokumentaci. Pro maximální pohodlí je vhodné využít JS/TS knihovnu megio-api, která vám bude našeptávat dostupné metody a parametry přímo při psaní kódu.
Pravidla pro entitu
Aby kolekce fungovala správně, je potřeba, aby zdrojová entita splňovala několik pravidel.
Hlavní pravidlo
Entita musí obsahovat 3 hlavní #[ORM]
atributy a musí implementovat rozhraní ICrudable
.
#[ORM\Entity]
#[ORM\Table(name: '`user`')]
#[ORM\HasLifecycleCallbacks]
class User implements ICrudable
{
use TId, TCreatedAt, TUpdatedAt;
}
Pravidlo pro relace
Jakákoliv entita ve vašem projektu, jenž je součástí nějaké relace může implementovat rozhraní IJoinable
.
Díky implementaci tohoto rozhraní dokáže datagrid automaticky zobrazit sloupec s relací a také správné editační políčko
pro formulář.
class Author implements IJoinable
{
#[ORM\Id]
#[ORM\Column(type: Types::GUID, unique: true)]
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
#[ORM\CustomIdGenerator(class: UuidV6Generator::class)]
protected string $id;
#[ORM\Column(length: 64)]
protected string $firstName;
#[ORM\Column(length: 64)]
protected string $lastName;
#[ORM\OneToMany(mappedBy: 'author', targetEntity: Article::class, fetch: 'LAZY')]
protected Collection $articles;
public function getId(): string
{
return $this->id;
}
public function getJoinableLabel(): array
{
return [
// Zdroj dat pro výpis v datagridu a API
'fields' => ['firstName', 'lastName'],
// Formát pro výpis dat v datagridu a API
'format' => '%s %s'
];
}
}
Velmi doporučené pravidlo
Doctrine ORM umožňuje definovat 4 typy relací: OneToOne
, OneToMany
, ManyToOne
a ManyToMany
.
Tyto relace je potřeba vždy definovat pomocí PHP atributů a hlavně je potřeba uvést parametry targetEntity
, mappedBy
či inversedBy
- jinak se kolekce nemusí chovat správně.
class Article
{
#[ORM\ManyToOne(targetEntity: Author::class, inversedBy: 'articles')]
#[ORM\JoinColumn(name: 'author_id', referencedColumnName: 'id')]
protected ?Author $author = null;
}
Megio díky těmto parametrům dokáže správně ukládat obousměrné relace do databáze (Doctrine ORM toto sama o sobě neumí). Pokud byste tyto parametry neuvedli, je potřeba vždy myslet na to, která entita vlastní relaci. Obecně to znamená, že byste vždy museli manuálně zajistit aktualizaci entity na straně vlastníka - snazší ale bude, když si zapamatujete toto pravidlo.