Атрибуты модели API-платформы доступны только для чтения - PullRequest
1 голос
/ 19 апреля 2019

Я борюсь с этим странным поведением моего API: некоторые атрибуты установлены на readOnly: true.

РЕДАКТИРОВАТЬ: Так определяются мои сущности

/**
 * @ApiResource(
 *     normalizationContext={"groups"={"read_partenaire"}},
 *     denormalizationContext={"groups"={"write_partenaire"}}
 * )
 * @ORM\Entity(repositoryClass="App\Repository\ProfessionnelRepository")
 * @ApiFilter(SearchFilter::class, properties={"nom": "partial", "id": "exact"})
 */

class Professionnel
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     * @Groups({"read_partenaire"})
     */
    private $id;

    /**
     * @ORM\OneToOne(targetEntity="App\Entity\Partenaire", cascade={"persist"})
     * @ORM\JoinColumn(nullable=false)
     * @Groups({"read_partenaire","write_partenaire"})
     *
     */
    private $partenaire;

    /**
     * @ORM\Column(type="string", length=4)
     * @Groups({"read_partenaire","write_partenaire"})
     *
     */
    private $civilite;

    /**
     * @ORM\Column(type="string", length=100)
     * @Groups({"read_partenaire","write_partenaire"})
     *
     */
    private $nom;

    /**
     * @ORM\Column(type="string", length=100)
     * @Groups({"read_partenaire","write_partenaire"})
     *
     */
    private $prenom;

Вторая сущность:

/**
 * @ApiResource(
 *     normalizationContext={"groups"={"read_partenaire"}},
 *     denormalizationContext={"groups"={"write_partenaire"}}
 * )
 * @ApiFilter(SearchFilter::class, properties={"id": "exact"})
 * @ORM\Entity(repositoryClass="App\Repository\PartenaireRepository")
 */
class Partenaire
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     * @Groups({"read_partenaire"})
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Ban", inversedBy="partenaires", cascade={"persist"})
     * @ORM\JoinColumn(nullable=false)
     * @Groups({"read_partenaire","write_partenaire"})

     */
    private $ban;

Третье лицо:

/**
 * @ApiResource()
 * @ORM\Entity(repositoryClass="App\Repository\BanRepository")
 */
class Ban
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     * @Groups({"read_partenaire"})
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     * @Groups({"read_partenaire","write_partenaire"})
     *
     */
    private $nom_voie;

Подводя итог, моя Professionnel сущность вложена в Partenaire, которая вложена в Ban. Таким образом, путем создания новых Professionnel должны быть созданы также новые Partenaire и Ban.

Имейте в виду, что все свойства моих трех сущностей имеют функции get и set (кроме идентификаторов, конечно) ... но по какой-то причине свойство nom_voie моей третьей сущности установлено на readOnly (и из-за этого вставка всех сущностей завершается неудачно ...) Here is the entity documentation I get

Я не уверен, как именно это двухуровневое вложение должно быть выражено с помощью Groups Я перепробовал много комбинаций, но не повезло ...

Ответы [ 2 ]

0 голосов
/ 19 апреля 2019

Вы должны обновить свою сущность следующим образом, вы не можете иметь одно и то же имя группы для нормализации и денормализации, теперь для свойств, которые вам нужно передать и прочитать их значение позже, добавьте в него обе группы {"ban_read", "ban_write "}, для идентификатора, например, необходим только" ban_read ", потому что вы не передадите значение идентификатора.

 * @ApiResource(
 *     normalizationContext={"groups"={"ban_read"}, "swagger_definition_name": "read"},
 *     denormalizationContext={"groups"={"ban_write"}, "swagger_definition_name": "write"}
 * )
 */ 
Class Address {
     //...  


     /**
     * @ORM\Column(type="integer")
     * @Groups({"ban_read"})
     */
    private $numero;

    /**
     * @ORM\Column(type="integer")
     * @Groups({"ban_write","ban_read"})
     */
    private $code_insee;

   //here you can see they both have identical getter and setter :

    public function getNumero(): ?int
    {
        return $this->numero;
    }

    public function setNumero(int $numero): self
    {
        $this->numero = $numero;

        return $this;
    }
    public function getCodeInsee(): ?int
    {
        return $this->code_insee;
    }

    public function setCodeInsee(int $code_insee): self
    {
        $this->code_insee = $code_insee;

        return $this;
       }
    }

UPDATE: Создайте уникальные группы для каждого объекта, например read_ban, write_ban, затем в объекте Professionnel обновите denormalizationContext, чтобы включить все остальные группы.

denormalizationContext={"groups"={"write_professionnel","write_partenaire", "write_ban"}}
0 голосов
/ 19 апреля 2019

Если вы хотите обрабатывать атрибуты только для чтения, я думаю, вы можете использовать контекст нормализации / денормализации вместо "getter / no setter"

Class Address {

 //...  


 /**
 * @ORM\Column(type="integer")
 * @Groups({"read", "write"})
 */
private $numero;

/**
 * @ORM\Column(type="integer")
 * @Groups({"read"})
 */
private $code_insee;


public function getNumero(): ?int
{
    return $this->numero;
}

public function setNumero(int $numero): self
{
    $this->numero = $numero;

    return $this;
}
public function getCodeInsee(): ?int
{
    return $this->code_insee;
}

public function setCodeInsee(int $code_insee): self
{
    $this->code_insee = $code_insee;

    return $this;
   }
}

и

services:
    # ...

resource.Address:
    parent:    "api.resource"
    arguments: [ "AppBundle\Entity\Address" ]
    calls:
        -      method:    "initNormalizationContext"
               arguments: [ { groups: [ "read" ] } ]
        -      method:    "initDenormalizationContext"
               arguments: [ { groups: [ "write" ] } ]
    tags:      [ { name: "api.resource" } ]
...