Wpis z mikrobloga

Ratunku, dlaczego w #symfony 5 nie działają constraints w formularzu przy edycji? (PUT api call)
Mam notBlank, przy create ładnie pokazuje "field cannot be blank" a przy update wykrzacza się dopiero na setterze w entity (setter spodziewa się stringa). update i create to ten sam formularz - update extends create z nowymi polami. Na pewno to coś głupiego ale od paru godzin nie mogę namierzyć :/

public function updateAction(Request $request, Device $device, EntityManagerInterface $entityManager): Response
{
$form = $this->createForm(DeviceUpdateType::class, $device);
$jsonData = json_decode($request->getContent(), true);
$form->submit($jsonData);

w formularzu:

->add('type', ChoiceType::class, [
'required' => true,
'choices' => Device::TYPES,
'multiple' => false,
'constraints' => [
new NotBlank(),
]
])

I tu się wykrzacza setter w entity :/

#php #programowanie
  • 17
  • Odpowiedz
  • Otrzymuj powiadomienia
    o nowych komentarzach

@gajowy_marucha: hmm, ale walidacja z tego co pamiętam jest odpalana już po zbindowaniu forma na obiekt, więc najpierw jest odpalany setter a dopiero później walidacja - dziwne, że działa Ci przy tworzeniu, bo powinien być ten sam problem, jeśli setter nie spodziewa się nulla. Najlepiej użyj jakiegoś DTO jako warstwy pośredniej miedzy encją a formem, a dopiero jeśli DTO przejdzie walidację, to na jego podstawie modyfikuj encję
  • Odpowiedz
dziwne, że działa Ci przy tworzeniu, bo powinien być ten sam problem, jeśli setter nie spodziewa się nulla.


@Kuzguwu: no właśnie :/ problem częściowo rozwiązuje PATCH i clear missing przy submit, może to i lepsze skoro tylko część pól ulega modyfikacji.
  • Odpowiedz
@gajowy_marucha: tak na szybko i brzydko, to możesz pozwolić na nulla w tym setterze, wtedy walidacja Ci powinna zadziałać, ale osobiście zawsze używam DTO w formach, jeśli chcę mieć encje zawsze w poprawnym stanie (bez "chwilowych" nulli)
  • Odpowiedz
@gajowy_marucha: właśnie dlatego użyj DTO i w nim pozwól na nulle. Sama encja będzie zawsze w poprawnym stanie, a DTO będzie pośrednikiem między formem a encją i tam nulle już Cię nie obchodzą
  • Odpowiedz
@gajowy_marucha: z reguły osobne DTO per formularz i jego walidujesz (ew później dodatkowa walidacja domenowa np w command handlerze). Właśnie DTO sprawia, że kod jest czytelniejszy i łatwiejszy do opanowania przy dużych projektach, jest bardziej zgodny z single responsibility principle, bo odseparowujesz logikę i model formularza od encji, szczególnie, że nie zawsze formularz odpowiada encji 1:1
  • Odpowiedz
@gajowy_marucha: przykład zmiany hasła:
masz encje User z polami np name, email, hashedPassword
formularz zmiany hasła ma pola plainPassword i plainPasswordRepeated

już masz rozbieżność, bo pola nie zgadzają się 1:1, pomimo, że formularz dotyczy encji Usera
Wprowadzając DTO jako "obiekt danych formularza potrzebnych do zmiany hasła" masz odseparowaną logikę formularza od encji, encja nie jest świadoma procesu zmiany hasła, walidacji tych danych, itp. Cała logika zmiany hasła może być odseparowana
  • Odpowiedz