We have a route where we can either give access or decline access to keys. When either one is done, an async message will be sent (and consumed with RabbitMQ).
This is what is in our Message class (triple dots mean a lot more parameters that have nothing to do with the issue):
public function __construct(private User $user, ...) {
public function getUser(): User {
return $this->user;
}
And this is what is in our MessageHandler class:
dd($message->getUser()->getPerson()->getFirstName());
This is the relationship for getPerson:
/**
* @ORM\OneToOne(targetEntity="App\Entity\Person", inversedBy="user")
* @ORM\JoinColumn(name="person_id", referencedColumnName="id", onDelete="SET NULL", nullable=true)
*/
private $person;
However, consuming the message, it will always dump null
. However, if I put this in the controller (right above where it dispatches the message):
dd($user->getPerson()->getFirstName());
It shows my first name fine. This is the function:
public function decline(Key $key, User $user, Form $declineForm, Actor $actor, Request $request, $bus) {
// ....
dd($user->getPerson()->getFirstName());
$bus->dispatch(new KeyConfirmationMessage($user, $key, $actor, $request->server->get('SERVER_NAME'), $reason));
// ...
}
And part of the route:
#[Route("/keys/save-access/{key}/{actor}/{user}", name: "keys_save_access")]
public function saveAccess(Key $key, Actor $actor, User $user, Request $request, KeyManager $keyManager, ManagerRegistry $doctrine, TranslatorInterface $translator, UnsafeKeyRepository $unsafeKeyRepo, SessionService $session, MessageBusInterface $bus) {
// ...
if ($declineForm->isSubmitted() && $declineForm->isValid()) {
return $keyManager->decline($key, $user, $declineForm, $actor, $request, $bus);
}
// ...
}
How can we make it so when trying to get the FirstName from getPerson
it will load the relationship correctly, just like how it's done in the controller? Both are similar codes but it seems like the relationship isn't fetched correctly in Messages and we have no clue why that is.
If you need to pass a Doctrine entity in a message, you should pass the entity's primary key or any relevant information the handler actually needs (in your case : firstName) instead of the object.
You can add your class for these changes:
You message class will be :
public function __construct(string $firstName, ...) {
public function getFirstName(): string {
return $this->firstName;
}
Inside your message handler, we can do this :
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function __invoke(KeyConfirmationMessage $message)
{
//$firstName = $this->userRepository->findByFirstName($message->getFirstName());
//...
//Retrieve the person first name here anyway
}
Finally, in your controller, before you dispatch, you will do:
$firstName = $user->getPerson()->getFirstName();
//Use firstName string instead
$bus->dispatch(new KeyConfirmationMessage($firstName, $key, $actor, $request->server->get('SERVER_NAME'), $reason));
// ...