mkultra
mkultra

Reputation: 21

POST to endpoint with relationship ReferenceMany in api platform

I have a issue posting to endpoint of api resource with relationship ReferenceMany

Action

<?php
/**
 * This file is part of the Tipzyy package.
 *
 * @author Fernando Paz <[email protected]>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
declare(strict_types=1);

namespace App\Shared\Domain\Action;

use ApiPlatform\Metadata\ApiResource;
use App\Shared\Domain\Default\StatusEnum;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
use Gedmo\Loggable\Loggable;
use Gedmo\Mapping\Annotation as Gedmo;

/**
 * Action class.
 */
#[Gedmo\Loggable]
#[MongoDB\Document(collection: 'action')]
#[ApiResource]
class Action implements Loggable
{
    #[MongoDB\Id(type: 'string', strategy: 'UUID')]
    private string $id;

    #[Gedmo\Versioned]
    #[MongoDB\Field(type: 'string', name: 'name', nullable: false)]
    #[MongoDB\Index]
    private string $name;

    #[Gedmo\Versioned]
    #[MongoDB\Field(type: 'string', name: 'desc', nullable: false)]
    private string $desc;

    #[Gedmo\Versioned]
    #[MongoDB\Field(type: 'string', name: 'status', nullable: false, enumType: StatusEnum::class)]
    private StatusEnum $status;

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

    public function setId(string $id): self
    {
        $this->id = $id;

        return $this;
    }

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

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

        return $this;
    }

    public function getDesc(): string
    {
        return $this->desc;
    }

    public function setDesc(string $desc): self
    {
        $this->desc = $desc;

        return $this;
    }

    public function getStatus(): StatusEnum
    {
        return $this->status;
    }

    public function setStatus(StatusEnum $status): self
    {
        $this->status = $status;

        return $this;
    }
}


AclGroup

<?php
/**
 * This file is part of the Tipzyy package.
 *
 * @author Fernando Paz <[email protected]>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
declare(strict_types=1);

namespace App\Shared\Domain\AclGroup;

use ApiPlatform\Metadata\ApiResource;
use App\Shared\Domain\Action\Action;
use App\Shared\Domain\Default\StatusEnum;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
use Gedmo\Loggable\Loggable;
use Gedmo\Mapping\Annotation as Gedmo;

/**
 * AclGroup class.
 */
#[Gedmo\Loggable]
#[MongoDB\Document(collection: 'acl-group')]
#[ApiResource]
class AclGroup implements Loggable
{
    #[MongoDB\Id(type: 'string', strategy: 'UUID')]
    private string $id;

    #[Gedmo\Versioned]
    #[MongoDB\Field(type: 'string', name: 'name', nullable: false)]
    #[MongoDB\Index]
    private string $name;

    #[Gedmo\Versioned]
    #[MongoDB\Field(type: 'string', name: 'desc', nullable: false)]
    private string $desc;

    #[Gedmo\Versioned]
    #[MongoDB\Field(type: 'string', name: 'status', nullable: false, enumType: StatusEnum::class)]
    private StatusEnum $status;

    #[MongoDB\ReferenceMany(name: 'acls', nullable: false, storeAs: 'dbRef' ,targetDocument: Action::class)]
    private ArrayCollection $acls;

    // Constructor AclGroup
    public function __construct()
    {
        $this->acls = new ArrayCollection();
    }

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

    public function setId(string $id): self
    {
        $this->id = $id;

        return $this;
    }

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

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

        return $this;
    }

    public function getDesc(): string
    {
        return $this->desc;
    }

    public function setDesc(string $desc): self
    {
        $this->desc = $desc;

        return $this;
    }

    public function getAcls(): ArrayCollection
    {
        return $this->acls;
    }

    public function setAcls(ArrayCollection $acls): self
    {
        $this->acls = $acls;

        return $this;
    }

    public function getStatus(): StatusEnum
    {
        return $this->status;
    }

    public function setStatus(StatusEnum $status): self
    {
        $this->status = $status;

        return $this;
    }
}

When post to /api/acl_groups

I have the next error

"Failed to denormalize attribute "acls" value for class "App\Shared\Domain\AclGroup\AclGroup": Expected argument of type "Doctrine\Common\Collections\ArrayCollection", "array" given at property path "acls"

I try with tests:

 public function testCreateAclGroup(): void
    {
        // The client implements Symfony HttpClient's `HttpClientInterface`, and the response `ResponseInterface`
        $client = static::createClient();

        // Actions
        $action = ActionFactory::new()
            ->withAttributes([
                'name' => 'Acl Group Create'
            ])
            ->create();
        $acls = [$this->getIriFromResource($action->object())];

        var_dump($acls);
        $client->request('POST', '/api/acl_groups', ['json' => [
            'name' => 'Test name',
            'desc' => 'Test description',
            'status' => StatusEnum::Active,
            'acls' => $acls
        ]]);
        // // Asserts that the client returns a 201 response
        $this->assertResponseStatusCodeSame(201);
    }

With array collection

    public function testCreateAclGroup(): void
    {
        // The client implements Symfony HttpClient's `HttpClientInterface`, and the response `ResponseInterface`
        $client = static::createClient();

        // Actions
        $action = ActionFactory::new()
            ->withAttributes([
                'name' => 'Acl Group Create'
            ])
            ->create();
      
            $actions = [$action->object()];
               $acls = new ArrayCollection($actions);

        var_dump($acls);
        $client->request('POST', '/api/acl_groups', ['json' => [
            'name' => 'Test name',
            'desc' => 'Test description',
            'status' => StatusEnum::Active,
            'acls' => $acls->toArray()
        ]]);
        // // Asserts that the client returns a 201 response
        $this->assertResponseStatusCodeSame(201);
    }

I think is something of deserialization but i dont find the solution.

Upvotes: 1

Views: 53

Answers (0)

Related Questions