php API平台未保持OneToMany关系

ars1skjm  于 2023-09-29  发布在  PHP
关注(0)|答案(1)|浏览(121)

我正在使用Doctrine继承的API平台,我在持久化OneToMany关系时遇到了问题。

curl --location 'http://localhost/api/dummies' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
  "fakeField": "string",
  "metadata": [
    {
      "name": "string",
      "value": "string"
    }
  ]
}'

响应将元数据返回为空数组,并且对象未在表中持久化。

{
  "id": "21f2051e-4dbe-4992-976d-ba3421c6aece",
  "fakeField": "string",
  "metadata": []
}

实体定义:

// ./src/Entity/AbstractMetadataAwareEntity.php

#[ORM\Entity]
#[ORM\Table(name: 'an_objects')]
#[ORM\InheritanceType('JOINED')]
#[ORM\DiscriminatorColumn(name: 'entity_type', type: 'string')]
#[ORM\DiscriminatorMap([
    'user' => User::class,
    'dummy' => Dummy::class,
])]
class AbstractMetadataAwareEntity
{
    #[ORM\Id]
    #[ORM\GeneratedValue(strategy: 'CUSTOM')]
    #[ORM\CustomIdGenerator(class: UuidGenerator::class)]
    #[ORM\Column(type: 'uuid', unique: true)]
    #[Groups(['base:read'])]
    protected UuidV6 $id;

    #[ORM\OneToMany(mappedBy: 'owner', targetEntity: Metadata::class, cascade: ['persist'])]
    #[Groups(['base:read', 'base:write'])]
    protected Collection $metadata;

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

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

    /**
     * @return Collection<int, Metadata>
     */
    public function getMetadata(): Collection
    {
        return $this->metadata;
    }

    public function addMetadata(Metadata $metadata): self
    {
        if (!$this->metadata->contains($metadata)) {
            $this->metadata->add($metadata);
            $metadata->setOwner($this);
        }

        return $this;
    }

    public function removeMetadata(Metadata $metadata): self
    {
        if ($this->metadata->removeElement($metadata)) {
            // set the owning side to null (unless already changed)
            if ($metadata->getOwner() === $this) {
                $metadata->setOwner(null);
            }
        }

        return $this;
    }
}
// ./src/Entity/Dummy.php

#[ORM\Entity(repositoryClass: DummyRepository::class)]
#[ApiResource(
    normalizationContext: [
        'groups' => ['base:read', 'dummy:read']
    ],
    denormalizationContext: [
        'groups' => ['base:write', 'dummy:write']
    ]
)]
class Dummy extends AbstractMetadataAwareEntity
{
    #[ORM\Column(length: 255)]
    #[Groups(['dummy:read', 'dummy:write'])]
    private ?string $fakeField = null;

    public function getFakeField(): ?string
    {
        return $this->fakeField;
    }

    public function setFakeField(string $fakeField): self
    {
        $this->fakeField = $fakeField;

        return $this;
    }
}
// ./src/Entity/Metadata.php

#[ORM\Entity(repositoryClass: MetadataRepository::class)]
#[ORM\Table(name: 'an_metadatas')]
class Metadata
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\Column(length: 255)]
    #[Groups(['base:read', 'base:write'])]
    private ?string $name = null;

    #[ORM\Column(length: 255)]
    #[Groups(['base:read', 'base:write'])]
    private ?string $value = null;

    #[ORM\ManyToOne(inversedBy: 'metadata')]
    #[ORM\JoinColumn(nullable: false)]
    private ?AbstractMetadataAwareEntity $owner = null;

    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 getValue(): ?string
    {
        return $this->value;
    }

    public function setValue(string $value): self
    {
        $this->value = $value;

        return $this;
    }

    public function getOwner(): ?AbstractMetadataAwareEntity
    {
        return $this->owner;
    }

    public function setOwner(?AbstractMetadataAwareEntity $owner): self
    {
        $this->owner = $owner;

        return $this;
    }
}

此实现使用Doctrine Inheritance
预期的结果是用户和元数据对象在各自表中的正确持久性

jqjz2hbq

jqjz2hbq1#

Dummy给出以下内容:

#[Groups(['dummy:read', 'dummy:write'])]
    private ?string $fakeField = null;

而响应显示"fakeField"的事实,我推断你有组'dummy:read''dummy:write',但是集合项不使用这两个组:

#[ORM\Column(length: 255)]
    #[Groups(['base:read', 'base:write'])]
    private ?string $name = null;

    #[ORM\Column(length: 255)]
    #[Groups(['base:read', 'base:write'])]
    private ?string $value = null;

因此,序列化数据中不包含任何属性值。尝试将'dummy:*'组添加到要返回的每个字段。

#[ORM\Column(length: 255)]
    #[Groups(['base:read', 'base:write', 'dummy:read', 'dummy:write'])]
    private ?string $name = null;

    #[ORM\Column(length: 255)]
    #[Groups(['base:read', 'base:write', 'dummy:read', 'dummy:write'])]
    private ?string $value = null;

对不起,我不是一个API平台的家伙。

相关问题