Skip to content

How to update instead of create a child entity that is not a @ApiResource nor a @ApiSubresource #1950

@Aerendir

Description

@Aerendir

I have a ThirdPartyEntity from a third party bundle that, using a ThirdPartyEntityTrait, I link to MyEntity in my project.

Now, as the ThirdPartyEntity is not set a ApiResource nor as an ApiSubresource and as I don't have any serializaton group set on MyEntity, when I get MyEntity from ApiPlatform, it returns me something like this:

{
   "@id":"/api/my_entities/17",
   "@type":"MyEntity",
   "id":17,
   "third_party_entity": {
      "id":22,
      "a_property":"some value"
   }
}

BUT IF I PUT a changed value for a_property with this body:

{
   "@id":"/api/my_entities/17",
   "@type":"MyEntity",
   "id":17,
   "third_party_entity": {
      "id":22,
      "a_property":"some NEW value to update"
   }
}

I get a new third_party_entity to be created and get this response:

{
   "@id":"/api/my_entities/17",
   "@type":"MyEntity",
   "id":17,
   "third_party_entity": {
      "id":23,
      "a_property":"some NEW value to update"
   }
}

SO, HOW CAN I UPDATE third_party_entity instead of creating it each time?

HERE THERE ARE THE INVOLVED CLASSES AND TRAITS

/**
 * @ORM\Table(name="app_my_entities")
 * @ORM\Entity()
 * @ApiResource()
 */
class MyEntity
{
    // !!!!!!!!!!!!!!!!!!
    // This is the trait I use to link MyEntity
    // with the entity from the third-party bundle
    // !!!!!!!!!!!!!!!!!!
    use ThirdPartyEntityTrait;

    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    ...
}

And this is the ThirdPartyEntityTrait:

trait ThirdPartyEntityTrait
{
    /**
     * @ORM\OneToOne(targetEntity="Namespace\To\Bundle\Entity\ThirdPartyEntity", cascade={"all"})
     * @ORM\JoinColumn(name="thirdPartyEntity", referencedColumnName="id")
     */
    private $thirdPartyEntity;

    /**
     * @param thirdPartyEntity $thirdPartyEntity
     *
     * @return ThirdPartyEntity
     */
    public function setThirdPartyEntity(thirdPartyEntity $thirdPartyEntity): ThirdPartyEntity
    {
        $this->thirdPartyEntity = $thirdPartyEntity;

        /** @var ThirdPartyEntity $this */
        return $this;
    }

    /**
     * @return thirdPartyEntity
     */
    public function getThirdPartyEntity(): ?thirdPartyEntity
    {
        return $this->thirdPartyEntity;
    }

    /**
     * @return thirdPartyEntity
     */
    public function removeThirdPartyEntity(): ?thirdPartyEntity
    {
        $thirdPartyEntity = $this->getThirdPartyEntity();

        $this->thirdPartyEntity = null;

        return $thirdPartyEntity;
    }
}

As you can see, nothing more a property to save the relation and some accessors methods.

This is, instead, the linked Entity:

/**
 * @ORM\Entity()
 * @ORM\Table(name="third_party_entities")
 */
class ThirdPartyEntity
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @ORM\Column(name="aProperty", type="string", nullable=true)
     */
    private $aProperty;

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

    public function getAProperty()
    {
        return $this->aProperty;
    }

    public function setAProperty($aProperty)
    {
        $this->aProperty = $aProperty;

        return $this;
    }
}

This question is cross-posted also on StackOverflow.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions