-
Hi, I am quite new to Symfony (so this is a BEGINNER question) and are just trying to implement a VERY simple web application:
That's all. Basically a CRUD without the "D", and yes, not super secure, but this is what we need. I thought this would be super easy with Symfony, leveraging doctrine and forms. Any yes, there are many good examples out there that describe how to easily build such an application, simply creating an entity (more or less a POPO with some validation rules), a respective form and type and a controller and then let Symfony do the work. Even the official documentation shws this with a "Task" object. Cool, 10 min work (at most) which I think is great for such a simple use case. Validation of new data as well as then saving new users is super easy. But the challenge I face: Whenever I want to change existing data, i.e. display the user's data and let her update it, she might do the mistake and delete some of the data, say her name. While in case of a new entry, the form validation would then show a user friendly error in that case (e.g., "Name should not be blank"), in case of an update, Symfony throws an exception, as a null value cannot be copied to what is expected to be a string.
I searched for that and found out that it is exactly what has been described here: #39106 It seems one should use DTOs and with that decouple the "business entity" (which should always be "valid") from form data (which may not). I really did a lot of searching, reading docs, even watching YT videos etc. - I simply cannot find a SIMPLE example on how this should work - the "update case" is never shown, only the "create" where you simply copy all form->data(). So I did it by myself, ending up with two more or less similar objects, one being the "entity" that is stored to/retrieved from the database with a couple of constraints (Non-Null, etc.) and one being the DTO with more or less the same data and the same constraints just used in the form (but despite the constraints technically allowing null properties!). And of course I wrote a lot of stupid code to copy data between the DTO and the business entity when preparing/processing the form. Question: Did I make a fundamental mistake in creating all the stupid DTO / copy code? If yes, can someone please help me finding a minimal example that avoids that and does validation properly for "null"-values in the update case? Comment: If I did NOT do a mistake and that is in general how it should work: I would say it is perfectly fine for more complex situations where the business entity really differs from the form data, e.g., because there is some more complex logic to derive the entity from the data etc. BUT: I strongly believe Symfony should provide an easy way for the simple "CRUD"-type of application - and as far as I can say, the "U" part is really annoying. Maybe one should have some sort of configuration value that makes the request handling in the form do it in a bit of a "relaxed" way (what obviously is the case when adding new data)? Thanks for any help! Jonas |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 7 replies
-
Fellow Symfony beginner here. I followed this Symfony tutorial on YT and it has some great tips to get started. If I understand your problem correctly, I believe your issue is coming from the validation at the ORM level. AFAIU the Form Type will do further validation at the ORM level if you've defined the 'data_class' in the class YourFormType extends AbstractType
{
// ...
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => YourDataEntity::class,
]);
}
} To clarify, in your Entity class, each attribute you want ensure is not blank should have the #[ORM\Entity(repositoryClass: YourDataRepository::class)]
class YourData
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 255)]
#[Assert\NotBlank()] // <----
#[Assert\Length(min: 3,max: 255)]
private ?string $name = null;
/// ...
} |
Beta Was this translation helpful? Give feedback.
-
Hi, thanks for your answer. Unfortunately, it does not really help. In general, I understand validation and how it works with the Assert decorators. This is not my problem, my code basically looks like your examples. The problem I have is in the "edit-case": My entity has all values set as expected and the form shows all the values. The user now deletes one of the mandatory fields. I would expect validation to give an error and the form to be redisplayed showing the error (something klik "field should not be empty". But: You can read many (probably beginner) people struggling with that. One is the github issue I linked to above (#39106 - EXACTLY my problem), another example can be found here: https://stackoverflow.com/questions/67772645/symfony-5-forms-and-entities-notblank-constraint-with-not-nullable-string-en and there are some others I do not have at hand right now. It seems a bit weird that a framework such as symfony that should make life simpler makes this so hard to implement and does not provide a good simple example. The "solutions" I found where:
I really wonder why there is no simple configuration value for a form to handle "null" values in requests in such simple cases... While I find many statements that "it should work that way", I do not find any good explanation/rationale. But as said, this all is a beginners POV. |
Beta Was this translation helpful? Give feedback.
-
It is one of those age old discussions that will never be settled. Kind of comforting in a way. Doctrine is database driven with one to one mappings between Doctrine entities and database tables. In principle your business entities should be database ignorant and designed strictly via business requirements. The On the other hand the fun stuff is where you actually have business entities that truly are database independent. It is typically worth the effort to have form specific DTO because the mapping is no longer just one to one. When it comes time to persist you really do need some custom logic to determine what data goes where. |
Beta Was this translation helpful? Give feedback.
It is one of those age old discussions that will never be settled. Kind of comforting in a way.
Doctrine is database driven with one to one mappings between Doctrine entities and database tables. In principle your business entities should be database ignorant and designed strictly via business requirements. The
problem
is that for a large portions of the applications I work on, Doctrine and business entities are the same. They are basically CRUD. So why bother introducing complexity that is not needed.On the other hand the fun stuff is where you actually have business entities that truly are database independent. It is typically worth the effort to have form specific DTO because the mapp…