Skip to content

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

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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions