-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
[Streamlining Entity Design] Introducing the DTOs #1522
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
||
#[ORM\Column] | ||
private \DateTimeImmutable $publishedAt; | ||
|
||
#[ORM\ManyToOne(targetEntity: User::class)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the targetEntity
is inferred from the property type
|
||
/** | ||
* @var Collection<int, Comment> | ||
*/ | ||
#[ORM\OneToMany(targetEntity: Comment::class, mappedBy: 'post', orphanRemoval: true, cascade: ['persist'])] | ||
#[ORM\OneToMany(targetEntity: Comment::class, mappedBy: 'post', cascade: ['persist'], orphanRemoval: true)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
resorting based on the argument definition
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; | ||
use Symfony\Component\Validator\Constraints as Assert; | ||
|
||
#[UniqueEntity(fields: ['slug'], message: 'post.slug_unique', entityClass: Post::class, errorPath: 'title', identifierFieldNames: ['id'])] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is now possible since Symfony 7.1
@@ -52,15 +52,18 @@ public function buildForm(FormBuilderInterface $builder, array $options): void | |||
->add('title', null, [ | |||
'attr' => ['autofocus' => true], | |||
'label' => 'label.title', | |||
'empty_data' => '', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[phpstan] this approach allows us to avoid nullable properties in the DTOs (forcing us to check for null before setting its value into a non-nullable argument)
If you remove the required
HTML attribute, the submitted form field data will be an empty string ''
instead of null
, and NotBlank
validator will do its job.
]) | ||
->add('content', null, [ | ||
->add('content', TextareaType::class, [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this improve the UX by adding more vertical space to work with the content input
{ | ||
$this->publishedAt = new \DateTimeImmutable(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why have you removed this? So, now the publish date is not set when the entity is constructed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was initially set up to provide a default value during the Post creation form, but its final value was always set through the setter, because it's currently a user input.
Now the default value is set in the DTO instead, and the Post::$publishedAt
value continues to be set through its setPublishedAt()
setter method.
Note that (as before) this proposal does not follow the stricter path to guarantee that the entity’s state is always valid from its construction which I'd like to (waiting for confirmation)
@@ -111,7 +111,6 @@ public function new( | |||
} | |||
|
|||
return $this->render('admin/blog/new.html.twig', [ | |||
'post' => $post, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed as it's useless in the template
Any news? |
I've made some updates to our entity designs to match what the community recommends about Forms -> DTOs -> Entities.
So, the
Post
entity is now separate from input/request processing, which is handled by the newPostDto
. I updated all Post's properties to meet business rules about nullability. For example, since the Post title is required, it’s no longer nullable. This also let me remove the phpstan exceptions about Entity <-> DB mapping mismatches.I kept things simple on purpose, but we might think about adding required properties in the constructor later (or through semantic constructors) to avoid invalid states.
These changes are only for the
Post
entity so far. If you like them, let me know, and I can update the rest.I'll add comments to clarify any changes that might not be immediately obvious.
Cheers!