symfony 4 + fosrestbundle - Jak załączyć obiekt

0

Cześć,
Z góry przepraszam za średnią nazwę wątku, nie wiedziałem jak lepiej to napisać.
Mam 2 tabele, jedna (tabela a) zawiera relację do innej (tabela b). Chciałbym wysłać request który stworzy obiekt (tabela) z relacją do pola z tabeli b. Jak mogę to automatycznie zmapować, nie musząc każdorazowo po przesłanym id pobierać obiektu z bazy i dopiero go przypisywać do pola obiektu tabeli a?

EDIT
Jedyne co wymyśliłem to customowy mapper (nie https://symfony.com/doc/master/bundles/SonataAdminBundle/cookbook/recipe_data_mapper.html) który jeśli obiekt istnieje weźmie jego entity. Macie jakieś lepsze rozwiązania?

Wcześniejsza wersja, używająca tylko fos'owych "bajerów":
Kontroler:

/**
 * @Route("/api")
 */
class ProjectController extends FOSRestController
{
    /**
     * @ParamConverter("project", converter="fos_rest.request_body")
     * @FOSRest\Post("/project")
     */
    public function postProjectAction(Project $project, ConstraintViolationList $violations)
    {
        if($violations->count()) {
            var_dump($violations);
        }

        $em = $this->getDoctrine()->getManager();
        $em->persist($project);
        $em->flush();
    }

}

Project.php:

<?php

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\ProjectRepository")
 * @UniqueEntity(
 *      fields={"name", "nameKey"}
 * )
 */
class Project
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     * @Assert\NotBlank()
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=140)
     * @Assert\NotBlank()
     */
    private $name;

    /**
     * @ORM\Column(type="string", length=5)
     * @Assert\NotBlank()
     */
    private $nameKey;

    /**
     * @ORM\Column(type="text", nullable=true)
     */
    private $description;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="assignedProjects")
     * @ORM\JoinColumn(nullable=false)
     */
    private $createdBy;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Priority")
     * @ORM\JoinColumn(nullable=false)
     */
    private $priority;

    /**
     * @ORM\ManyToMany(targetEntity="App\Entity\User", inversedBy="projects")
     */
    private $assignedUsers;

    /**
     * @ORM\Column(type="datetime", nullable=true)
     */
    private $deadline;

    /**
     * @ORM\ManyToMany(targetEntity="App\Entity\Customer", inversedBy="projects")
     */
    private $assignedCustomers;

    /**
     * @ORM\Column(type="boolean")
     */
    private $active;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Task", inversedBy="assignedProject")
     */
    private $tasks;

    /**
     * @ORM\Column(type="datetime")
     */
    private $createdAt;

    public function __construct()
    {
        $this->assignedUsers = new ArrayCollection();
        $this->assignedCustomers = new ArrayCollection();
    }

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

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }

    public function getNameKey(): ?string
    {
        return $this->nameKey;
    }

    public function setNameKey(string $nameKey): self
    {
        $this->nameKey = $nameKey;

        return $this;
    }

    public function getDescription(): ?string
    {
        return $this->description;
    }

    public function setDescription(?string $description): self
    {
        $this->description = $description;

        return $this;
    }

    public function getCreatedBy(): ?User
    {
        return $this->createdBy;
    }

    public function setCreatedBy(?User $createdBy): self
    {
        $this->createdBy = $createdBy;

        return $this;
    }

    public function getPriority()
    {
        return $this->priority;
    }

    public function setPriority($priority): self
    {
        $this->priority = $priority;

        return $this;
    }

    /**
     * @return Collection|User[]
     */
    public function getAssignedUsers()
    {
        return $this->assignedUsers;
    }

    public function addAssignedUser(User $assignedUser): self
    {
        if (!$this->assignedUsers->contains($assignedUser)) {
            $this->assignedUsers[] = $assignedUser;
        }

        return $this;
    }

    public function removeAssignedUser(User $assignedUser): self
    {
        if ($this->assignedUsers->contains($assignedUser)) {
            $this->assignedUsers->removeElement($assignedUser);
        }

        return $this;
    }

    public function getDeadline(): ?\DateTimeInterface
    {
        return $this->deadline;
    }

    public function setDeadline(?\DateTimeInterface $deadline): self
    {
        $this->deadline = $deadline;

        return $this;
    }

    /**
     * @return Collection|Customer[]
     */
    public function getAssignedCustomers()
    {
        return $this->assignedCustomers;
    }

    public function addAssignedCustomer(Customer $assignedCustomer): self
    {
        if (!$this->assignedCustomers->contains($assignedCustomer)) {
            $this->assignedCustomers[] = $assignedCustomer;
        }

        return $this;
    }

    public function removeAssignedCustomer(Customer $assignedCustomer): self
    {
        if ($this->assignedCustomers->contains($assignedCustomer)) {
            $this->assignedCustomers->removeElement($assignedCustomer);
        }

        return $this;
    }

    public function getActive(): ?bool
    {
        return $this->active;
    }

    public function setActive(bool $active): self
    {
        $this->active = $active;

        return $this;
    }

    public function getTasks(): ?Task
    {
        return $this->tasks;
    }

    public function setTasks(?Task $tasks): self
    {
        $this->tasks = $tasks;

        return $this;
    }

    public function getCreatedAt(): ?\DateTimeInterface
    {
        return $this->createdAt;
    }

    public function setCreatedAt(\DateTimeInterface $createdAt): self
    {
        $this->createdAt = $createdAt;

        return $this;
    }
}

1

Akurat za bardzo symfony nie znam, ale wszystko wskazuje na zwykłą relację, którą powinno ogarnąć ORM.
Wybierz relację jaka najbardziej odpowiada Twojemu schematowi i tyle: https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/association-mapping.html

0
jurek1980 napisał(a):

Akurat za bardzo symfony nie znam, ale wszystko wskazuje na zwykłą relację, którą powinno ogarnąć ORM.
Wybierz relację jaka najbardziej odpowiada Twojemu schematowi i tyle: https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/association-mapping.html

Zaraz do 1 postu załączę kod. Relację mam zrobioną, niestety fos'owy konwertert przekazuje same parametry, bez zwracania uwagi czy pole wskazuje na jakąś relację. W wielkim skrócie... Zamiast pobrać entity o id 1 i przekazać, przekazuje po prostu 1.

1 użytkowników online, w tym zalogowanych: 0, gości: 1