Error using an AssociationField with a nested property since v4.27.0
After updating to EAB version 4.27.0 I get an error on one of my index sites:
The "ccm.company" field is not a Doctrine association, so it cannot be used as an association field.
I use an AssociationField with the following syntax:
yield AssociationField::new('ccm.company', 'Company')
->setCrudController(CompanyCrudController::class);
ccm and company are many to one relations in their respective parent entity. I use the AssociationField to have a clickable value in the Company column. It still works when I change to TextField for example.
A bit of debugging showed me that the validation of the property names changed in the AssociationConfigurator from
public function configure(FieldDto $field, EntityDto $entityDto, AdminContext $context): void
{
$propertyName = $field->getProperty();
if (!$entityDto->isAssociation($propertyName)) {
throw new \RuntimeException(sprintf('The "%s" field is not a Doctrine association, so it cannot be used as an association field.', $propertyName));
}
...
public function isAssociation(string $propertyName): bool
{
return $this->metadata->hasAssociation($propertyName)
|| (str_contains($propertyName, '.') && !$this->isEmbeddedClassProperty($propertyName)); <--- allows nested properties
}
to
public function configure(FieldDto $field, EntityDto $entityDto, AdminContext $context): void
{
$propertyName = $field->getProperty();
if (!$entityDto->getClassMetadata()->hasAssociation($propertyName)) {
throw new \RuntimeException(sprintf('The "%s" field is not a Doctrine association, so it cannot be used as an association field.', $propertyName));
}
Is there any plan to fix this and allow nested properties here? Or am I using this in a wrong way? Until now it worked for me.
Thank you in advance.
I could fix it testwise by rolling back some of the refactoring of #7175 and #7193 like this:
public function configure(FieldDto $field, EntityDto $entityDto, AdminContext $context): void
{
$propertyName = $field->getProperty();
if (!$entityDto->isAssociation($propertyName)) { <--------------
throw new \RuntimeException(sprintf('The "%s" field is not a Doctrine association, so it cannot be used as an association field.', $propertyName));
}
$targetEntityFqcn = $field->getDoctrineMetadata()->get('targetEntity'); <----------------
I think I found a BC break here - unlike than said :(
What do you think about my case here, @michaelKaefer, @javiereguiluz? I would be very thankful about some help.
@screenflavor I'm not sure because I never used it but does EA really support nested fields like 'ccm.company'? I had a quick look at the docs but couldn't find an answer to this question. Not sure but I tend to think that it's not supported (even if it worked in your case).
@screenflavor I'm not sure because I never used it but does EA really support nested fields like
'ccm.company'? I had a quick look at the docs but couldn't find an answer to this question. Not sure but I tend to think that it's not supported (even if it worked in your case).
Yes, it's (was) supported to use a nested object of a nested object :D. In our company, we're using it quite often.
For instance, for a user entity you could've used apartment.internetProvider which is a chain of 3 objects in total: user (entity) -> apartment (entity) -> internetProvider (entity)
@siggidiel I know that it worked but my question is if it is supported.
If something has worked before even if it was not documented well should it be the case for it to stop working?
At our company we are also using nested association fields e.g. for displaying nested association on index pages.
cc @michaelKaefer
The removed check was wrong. It also passed if you used a nonsense string like "foo.bar.notexistinganything". Simply reintroducing this wrong check would be wrong.
Maybe someone wants to add a new check which checks for nested associations and if they can be used for AssociationField. I don't know if it would be merged though, because I don't know if EA wants to support this use case.
I also think there are other ways to do the same thing without AssociationField like this.