Home > Mobile >  How to serialize single field from ManyToOne column
How to serialize single field from ManyToOne column

Time:07-13

I have Users and Message Entity, which has relation of OneToMany. Currently API response looks something like this:

{
    "data": {
        "messages": [
            {
                "id": "1ed01e01-3e73-6b62-bdcb-3de4f998be6c",
                "toUser": {
                    "id": "1ed01e01-1133-690e-8ac8-6b6e91ccf39b",
                    "__initializer__": [],
                    "__cloner__": [],
                    "__isInitialized__": false
                },
                "fromUser": {
                    "id": "1ed01e01-1133-671a-8d31-6b6e91ccf39b",
                    "__initializer__": [],
                    "__cloner__": [],
                    "__isInitialized__": false
                },
                "createdAt": "2022-07-12T15:42:23 03:00",
                "content": "Content."
            }
        ],
        "count": 1
    }
}

I would like toUser and fromUser only display their id without rest of fields from Message Entity, like so:

"toUser": "1ed01e01-1133-690e-8ac8-6b6e91ccf39b",
"fromUser": "1ed01e01-1133-671a-8d31-6b6e91ccf39b"

Here is how my entities and serialization looks like. User.php

#[ORM\Entity(repositoryClass: UserRepository::class)]
#[ORM\Table(name: '`user`')]
class User
{
    #[ORM\Id]
    #[ORM\Column(type: 'uuid', unique: true)]
    #[ORM\GeneratedValue(strategy: "CUSTOM")]
    #[ORM\CustomIdGenerator(class: 'doctrine.uuid_generator')]
    private $id;


    #[ORM\Column(type: 'string', length: 255, unique: true)]
    private $username;

    #[ORM\OneToMany(mappedBy: 'toUser', targetEntity: Message::class, orphanRemoval: true)]
    private $messages;
...
}

Messages.php

#[ORM\Entity(repositoryClass: MessageRepository::class)]
class Message
{
    #[ORM\Id]
    #[ORM\Column(type: 'uuid', unique: true)]
    #[ORM\GeneratedValue(strategy: "CUSTOM")]
    #[ORM\CustomIdGenerator(class: 'doctrine.uuid_generator')]
    private $id;

    #[ORM\ManyToOne(targetEntity: User::class, inversedBy: 'messages')]
    #[ORM\JoinColumn(nullable: false)]
    private $toUser;

    #[ORM\ManyToOne(targetEntity: User::class, inversedBy: 'messages')]
    #[ORM\JoinColumn(nullable: false)]
    private $fromUser;

    #[ORM\Column(type: 'datetime_immutable')]
    private $createdAt;

    #[ORM\Column(type: 'datetime', nullable: true)]
    private $updatedAt;

    #[ORM\Column(type: 'text')]
    private $content;

    public function getId(): ?UuidV6
    {
        return $this->id;
    }
}

MessageController.php


public function getAllMessages() {
  $serialized = $serializer->serialize($messages, 'json', [
            ObjectNormalizer::SKIP_NULL_VALUES => true,
            ObjectNormalizer::IGNORED_ATTRIBUTES => ['username', 'messages', 'created_at'],
            ObjectNormalizer::CIRCULAR_REFERENCE_HANDLER => function ($object) {
                return $object->getId();
            },
        ]);
        $dataMessage = json_decode($serialized);

        $json = json_encode([
            "data" => array("recipients" => $dataMessage, "count" => count($dataMessage))
        ]);
}

CodePudding user response:

I think the best would be to create a models class to formalize your data. At least you are sure that you manage your object 100% and it does not show you any useless attribute

class MessageModel
{
    public int $id;
    public string $toUser;
    public string $fromUser;
    public string $createdAt;
    public string $content;
    /**
     * @param Message $message
     */
    public function __construct(Message $message)
    {
        $this->id = $message->getId();
        $this->toUser = $message->getUser()->getId()
        $this->fromUser = $message->getUser()->getId()
        $this->createdAt = $message->getCreatedAt()->format('d/m/Y H:i:s');
        $this->updatedAt = $message->getUpdatedAt() === null ? '' : $message->getUpdatedAt()->format('d/m/Y H:i:s');
        $this->content = $message->getContent();
    }

    /**
     * @return $this
     */
    public function build(): MessageModel
    {
        return $this;
    }
}

for the code I let you adapt it I have not tested

  • Related