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 :/
@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ę
@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)
@gajowy_marucha: @Kuzguwu: też nigdy nie używam encji w formach. Tak jak @Kuzguwu encje chcę mieć zawsze w "poprawnym" stanie. Swego czasu wydzieliłem z jednego projektu prosty bundle (nakładka na Argument resolver), dzięki któremu w ogóle nie operuję na formularzach tylko DTO jako argumenty w akcjach controllera. Może się przyda: https://github.com/prugala/symfony-request-dto :)
@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ą
@Kuzguwu: Przy dużej aplikacji nie utrudnia to panowania nad kodem? Rozumiem, że DTO piszemy pod konkretny formularz a nie encję? Gdzie zachodzi walidacja, pewnie wszędzie lub tylko w encji i DTO?
@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
@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
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
Komentarz usunięty przez autora
Komentarz usunięty przez autora
@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.
Swego czasu wydzieliłem z jednego projektu prosty bundle (nakładka na Argument resolver), dzięki któremu w ogóle nie operuję na formularzach tylko DTO jako argumenty w akcjach controllera. Może się przyda: https://github.com/prugala/symfony-request-dto :)
edit:
chyba nie do przejścia :/
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
@Kuzguwu: tzn formularz? Rozumiem, że Encja nadal ma swoje asserty wymuszające poprawność? To chyba spowoduje duplikowanie komunikatów o błędach?