将 Doctrine Entity 中的子项过滤为 属性 和 mutate/hydrate 表单输入
Filter children in Doctrine Entity as property and mutate/hydrate form input
我正在使用 Symfony 3.2 和 Doctrine 2.5 开发一个带有 API 端点的文章数据库。在请求正文中,我有一个作者:
{
"article": {
"title": "Some article",
"author": {
"email": "someone@something.com",
"name": "Howard Wedothis"
}
}
}
我想存储一个带有日期时间、文章 ID 和作者 ID 的更新实体。目前,为了做到这一点,我必须 post 以下内容:
{
"article": {
"title": "Some article",
"updates": [{
"author": {
"email": "someone@something.com",
"name": "Howard Wedothis"
}
}]
}
}
这不像 IMO 那样优雅。
第一个问题: mutate/hydrate 简单作者字段并存储针对文章和作者的更新的最佳方法是什么?作者和文章是 ManyToMany,但我想避免 post 主要出于可读性原因而使用一个数组。
第二个问题:是否可以为created
和lastUpdated
的文章实体添加属性,分别显示来自没有将存储库注入实体的文章?
即
$article->getCreated() // returns first Update
$article->getLastUpdated() // returns last Update
第二个问题的答案——使用Lifecycle Callbacks
<?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')));
}
}
}
http://symfony.com/doc/current/doctrine/lifecycle_callbacks.html
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html#lifecycle-events
关于您的请求示例,插入请求和更新请求应该具有相同的格式。 updates 键让你的生活变得复杂。
使用 POST 方法插入文章和 PUT(发送完整的文章对象)或 PATCH(仅发送要更新的字段)。
https://knpuniversity.com/screencast/rest/put-versus-post
https://knpuniversity.com/screencast/symfony-rest/patch-programmer
最后,我按照@Matko 的建议,通过添加作者并在更新时覆盖作者并使用生命周期事件在 PrePersist 和 PreUpdated 上创建新的更新实体来解决这个问题。
请求数据:
{
"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);
}
}
此方法确实会使实体的作者无效,但会保留文章历史记录。
我正在使用 Symfony 3.2 和 Doctrine 2.5 开发一个带有 API 端点的文章数据库。在请求正文中,我有一个作者:
{
"article": {
"title": "Some article",
"author": {
"email": "someone@something.com",
"name": "Howard Wedothis"
}
}
}
我想存储一个带有日期时间、文章 ID 和作者 ID 的更新实体。目前,为了做到这一点,我必须 post 以下内容:
{
"article": {
"title": "Some article",
"updates": [{
"author": {
"email": "someone@something.com",
"name": "Howard Wedothis"
}
}]
}
}
这不像 IMO 那样优雅。
第一个问题: mutate/hydrate 简单作者字段并存储针对文章和作者的更新的最佳方法是什么?作者和文章是 ManyToMany,但我想避免 post 主要出于可读性原因而使用一个数组。
第二个问题:是否可以为created
和lastUpdated
的文章实体添加属性,分别显示来自没有将存储库注入实体的文章?
即
$article->getCreated() // returns first Update
$article->getLastUpdated() // returns last Update
第二个问题的答案——使用Lifecycle Callbacks
<?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')));
}
}
}
http://symfony.com/doc/current/doctrine/lifecycle_callbacks.html http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html#lifecycle-events
关于您的请求示例,插入请求和更新请求应该具有相同的格式。 updates 键让你的生活变得复杂。
使用 POST 方法插入文章和 PUT(发送完整的文章对象)或 PATCH(仅发送要更新的字段)。
https://knpuniversity.com/screencast/rest/put-versus-post
https://knpuniversity.com/screencast/symfony-rest/patch-programmer
最后,我按照@Matko 的建议,通过添加作者并在更新时覆盖作者并使用生命周期事件在 PrePersist 和 PreUpdated 上创建新的更新实体来解决这个问题。
请求数据:
{
"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);
}
}
此方法确实会使实体的作者无效,但会保留文章历史记录。