Autoload association in OneToMany relation
When you create your custom entity with definition, collection, migration, etc. probably you want to autoload this association to another entity. The problem is in the OneToMany association because here we don't have an option autoload.
The problem
Let's say that we want to extend the customer entity about tickets. In this case, we have a OneToMany relation - One client can have multiple tickets but the ticket can have one owner.
After creating a ticket entity with definition, collection, migration, etc you will notice that the OneToMany relation doesn't have autoload. In most cases, it will not be a problem because we will add a specific association in the Criteria but what the situation where we can not modify the Criteria - I mean a custom rule and match method.
public function match(RuleScope $scope): bool
{
}
Without autoload we can not do something like:
public function match(RuleScope $scope): bool
{
$scope->getSalesChannelContext()->getCustomer()->getExtensions()
}
According to the documentation, we should stick to the RuleScope $scope and DO NOT any database queries because this can have a drastic time consuming on the performance. What option do we have in this case?
Solution
We need to add the association when entities are loaded. To do it globally we can subscribe to EntitySearchedEvent and add the association to the criteria. This should make the extension available globally.
class EntitySearchSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
EntitySearchedEvent::class => 'onEntitySearch',
];
}
public function onEntitySearch(EntitySearchedEvent $event): void
{
if ($event->getDefinition()->getEntityName() !== CustomerDefinition::ENTITY_NAME) {
return;
}
$event->getCriteria()->addAssociation('ticket');
}
}
Comments
H4ck3r
h@cker.plJan 12, 2024
Very helpful, clearly a good expert! 👌☝️