Doctrine 将条令实体中的子项筛选为属性,并对表单输入进行变异/水合

Doctrine 将条令实体中的子项筛选为属性,并对表单输入进行变异/水合,doctrine,symfony,entity-relationship,symfony-forms,Doctrine,Symfony,Entity Relationship,Symfony Forms,我正在使用Symfony 3.2和Doctrine 2.5开发一个带有API端点的文章数据库。在请求正文中,我有一位作者: { "article": { "title": "Some article", "author": { "email": "someone@something.com", "name": "Howard Wedothis" } } } 我想用datetime、article

我正在使用Symfony 3.2和Doctrine 2.5开发一个带有API端点的文章数据库。在请求正文中,我有一位作者:

{
   "article": {
       "title": "Some article",
       "author": {
           "email": "someone@something.com",
           "name": "Howard Wedothis"
       }
   }
}
我想用datetime、article ID和Author ID存储更新实体。为了当前执行此操作,我必须发布以下内容:

{
    "article": {
        "title": "Some article",
        "updates": [{
            "author": {
                "email": "someone@something.com",
                "name": "Howard Wedothis"
            }
        }]
    }
}
在我看来,这不是那么优雅

第一个问题:改变/补充简单作者字段并根据文章和作者存储更新的最佳方法是什么?作者和文章很多,但出于可读性的原因,我不想发布一系列的作者和文章

第二个问题:是否可以为
创建的
上次更新的
向文章实体添加属性,以分别显示文章中的第一次和最后一次更新,而无需将存储库注入实体

i、 e


第二个问题的答案-使用生命周期回调

<?php

use Doctrine\ORM\Mapping as ORM;

/** 
 * @ORM\HasLifecycleCallbacks
 */
class Author
{
    ...

    /**
     * @ORM\Column(type="datetime")
     */
    protected $createdAt;

    /**
     * @ORM\Column(type="datetime")
     */
    protected $updatedAt;

    /**
     * Get id.
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set createdAt.
     *
     * @param \DateTime $createdAt
     *
     * @return this
     */
    public function setCreatedAt($createdAt)
    {
        $this->createdAt = $createdAt;

        return $this;
    }

    /**
     * Get createdAt.
     *
     * @return \DateTime
     */
    public function getCreatedAt()
    {
        return $this->createdAt;
    }

    /**
     * Set modifiedAt.
     *
     * @param \DateTime $updatedAt
     *
     * @return Article
     */
    public function setUpdatedAt($updatedAt)
    {
        $this->updatedAt = $updatedAt;

        return $this;
    }

    /**
     * Get updatedAt.
     *
     * @return \DateTime
     */
    public function getUpdatedAt()
    {
        return $this->updatedAt;
    }

    ...

    /**
     * @ORM\PrePersist
     * @ORM\PreUpdate
     */
    public function updatedTimestamps()
    {
        $this->setUpdatedAt(new \DateTime(date('Y-m-d H:i:s')));

        if ($this->getCreatedAt() == null) {
            $this->setCreatedAt(new \DateTime(date('Y-m-d H:i:s')));
        }
    }
}

第二个问题的答案-使用生命周期回调

<?php

use Doctrine\ORM\Mapping as ORM;

/** 
 * @ORM\HasLifecycleCallbacks
 */
class Author
{
    ...

    /**
     * @ORM\Column(type="datetime")
     */
    protected $createdAt;

    /**
     * @ORM\Column(type="datetime")
     */
    protected $updatedAt;

    /**
     * Get id.
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set createdAt.
     *
     * @param \DateTime $createdAt
     *
     * @return this
     */
    public function setCreatedAt($createdAt)
    {
        $this->createdAt = $createdAt;

        return $this;
    }

    /**
     * Get createdAt.
     *
     * @return \DateTime
     */
    public function getCreatedAt()
    {
        return $this->createdAt;
    }

    /**
     * Set modifiedAt.
     *
     * @param \DateTime $updatedAt
     *
     * @return Article
     */
    public function setUpdatedAt($updatedAt)
    {
        $this->updatedAt = $updatedAt;

        return $this;
    }

    /**
     * Get updatedAt.
     *
     * @return \DateTime
     */
    public function getUpdatedAt()
    {
        return $this->updatedAt;
    }

    ...

    /**
     * @ORM\PrePersist
     * @ORM\PreUpdate
     */
    public function updatedTimestamps()
    {
        $this->setUpdatedAt(new \DateTime(date('Y-m-d H:i:s')));

        if ($this->getCreatedAt() == null) {
            $this->setCreatedAt(new \DateTime(date('Y-m-d H:i:s')));
        }
    }
}

最后,我解决了这个问题,在更新时添加作者并覆盖作者,并使用生命周期事件在PrePersist上创建一个新的更新实体,并按照@Matko的建议进行预更新

请求数据:

{
   "article": {
       "title": "Some article",
       "author": {
           "email": "someone@something.com",
           "name": "Howard Wedothis"
       }
   }
}
Article.php:

/**
 * @ORM\Entity
 * @ORM\Table(name="articles")
 * @ORM\HasLifecycleCallbacks
 */
class Article
{
    /**
     * @return Update
     */
    public function getCreated(): Update
    {
        return $this->updates->first();
    }

    /**
     * @return Update
     */
    public function getLastUpdated(): Update
    {
        return $this->updates->last();
    }

    /**
     * @ORM\PrePersist
     * @ORM\PreUpdate
     */
    public function addUpdate(): void
    {
        $update = new Update();
        $update->setAuthor($this->getAuthor());
        $update->setArticle($this);
        $this->updates->add($update);
    }
}

此方法确实会使实体的作者失效,但会保留文章历史记录。

最后,我通过添加作者并在更新时覆盖作者,以及使用生命周期事件在PrePersist上创建一个新的更新实体,并按照@Matko的建议进行预更新来解决此问题

请求数据:

{
   "article": {
       "title": "Some article",
       "author": {
           "email": "someone@something.com",
           "name": "Howard Wedothis"
       }
   }
}
Article.php:

/**
 * @ORM\Entity
 * @ORM\Table(name="articles")
 * @ORM\HasLifecycleCallbacks
 */
class Article
{
    /**
     * @return Update
     */
    public function getCreated(): Update
    {
        return $this->updates->first();
    }

    /**
     * @return Update
     */
    public function getLastUpdated(): Update
    {
        return $this->updates->last();
    }

    /**
     * @ORM\PrePersist
     * @ORM\PreUpdate
     */
    public function addUpdate(): void
    {
        $update = new Update();
        $update->setAuthor($this->getAuthor());
        $update->setArticle($this);
        $this->updates->add($update);
    }
}

此方法确实会使实体的作者无效,但会保留文章历史记录。

谢谢-但是,通过更新单个字段,我将丢失作者信息。如果一个人创建了文章,另一个人更新了它,我没有更新信息。因此希望保留修订/更新历史。关于POST/PUT等。是的-这就是API的工作方式-示例使用键而不是方法突出了问题。因此,我希望仅从author键创建这个更详细的元信息,而不必在requestThank中指定完整的负载——但是,通过更新单个字段,我将丢失author信息。如果一个人创建了文章,另一个人更新了它,我没有更新信息。因此希望保留修订/更新历史。关于POST/PUT等。是的-这就是API的工作方式-示例使用键而不是方法突出了问题。因此,我希望仅从作者密钥创建更详细的元信息,不必在请求中指定完整负载,我认为您必须处理引用表中额外列的多对多关系:您可以看看这个问题:我认为您必须处理引用表中额外列的多对多关系:您可以看看这个问题: