Php Symfony2时间表包含相关实体的更新
我正在尝试使用Symfony2创建一个应用程序,但遇到了一些我无法理解的问题。我有一个名为公司的实体和另一个名为地址的实体,具有多对多关系(应该是一对多,但我认为这是Symfony/Doctrine处理它的方式)。i、 e.每个公司可以有一个或多个地址。我已经设置了Gedmo的条令扩展,并且在这两个实体上都使用了timestable。我已经建立了一个更新两个链接实体的表单,但我真正希望的是,如果地址得到更新,能够为公司添加时间戳,因为它是这两个实体的所有者 有人知道Timestable是否能做到这一点,或者我可能做错了什么吗 你可以在这里看到我的公司课程:Php Symfony2时间表包含相关实体的更新,php,symfony,doctrine-orm,Php,Symfony,Doctrine Orm,我正在尝试使用Symfony2创建一个应用程序,但遇到了一些我无法理解的问题。我有一个名为公司的实体和另一个名为地址的实体,具有多对多关系(应该是一对多,但我认为这是Symfony/Doctrine处理它的方式)。i、 e.每个公司可以有一个或多个地址。我已经设置了Gedmo的条令扩展,并且在这两个实体上都使用了timestable。我已经建立了一个更新两个链接实体的表单,但我真正希望的是,如果地址得到更新,能够为公司添加时间戳,因为它是这两个实体的所有者 有人知道Timestable是否能做到
<?php
// src/Amber/AtsBundle/Entity/Company.php
namespace Amber\AtsBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
//...
use Doctrine\Common\Collections\ArrayCollection;
/**
* Company
*
* @ORM\Table()
* @ORM\Entity
*/
class Company
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\ManyToMany(targetEntity="Address", cascade={"persist"})
* @ORM\JoinTable(name="company_addresses",
* joinColumns={@ORM\JoinColumn(name="company_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="address_id", referencedColumnName="id", unique=true)}
* )
**/
private $addresses;
public function __construct()
{
$this->addresses = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* @var datetime $created
*
* @Gedmo\Timestampable(on="create")
* @ORM\Column(type="datetime")
*/
private $created;
/**
* @var datetime $updated
*
* @Gedmo\Timestampable(on="update")
* @ORM\Column(type="datetime")
*/
private $updated;
如果您有任何帮助,我将不胜感激。我想时间戳不会检查相关实体上的更改 解决方案是在公司和地址之间建立一种双向的一对多关系,公司是所有权方 公司
/**
* @ORM\OneToMany(targetEntity="Address", inversedBy="company", cascade={"persist"})
*/
protected $addresses;
地址
/**
* @ORM\ManyToOne(targetEntity="Company", mappedBy="adresses")
*/
protected $company;
public function getCompany()
{
return $this->company;
}
public function setCompany($company)
{
$this->company = $company;
return $this;
}
// now the the tricky part
public function setUpdated($updated)
{
$this->updated = $updated;
if ( $updated > $this->company->getUpdated() )
{
$this->company->setUpdated($updated);
}
return $this;
}
如果多个公司可以具有相同的地址,并在所有关联公司上循环,则可以使用多对多,如下所示:
public function setUpdated($updated)
{
$this->updated = $updated;
foreach ($this->companies as $company) {
if ( $updated > $this->company->getUpdated() )
{
$this->company->setUpdated($updated);
}
}
return $this;
}
相应地调整映射注释,但我想你明白了…请查看我的评论,如果有任何不清楚的地方请发表评论,否则请接受答案:)另一个提示:请查看@ParamConverter以清理控制器->谢谢,这是一个很好的解决方案,我的问题是,我计划使用Address实体来服务其他人,例如Person。因此,我希望能够在上下文地址更新时给公司加上时间戳,或者在上下文更新另一个实体,如Person。在本例中,向地址实体添加一个非持久性属性(和getter/setter)上下文,并设置它(在_构造中或使用依赖项注入)作为AddressFormType中的隐藏输入。在地址实体上包含一个开关,如$this->{$this->context}=$updated。。。如果构建包含上下文的表单,bindRequest将使地址具有上下文“公司”或“个人”,并且仅更新这些内容!但是如果你想要更详细的信息,请接受我的回答,并用一个新的问题来回答:)你的回答让我思考,我想我已经整理好了我想要的,谢谢你的帮助。解决方案是在控制器中添加一些代码,刷新更改,比较日期,必要时更新“更新”,然后再次刷新更改。请参见下文($form->isValid()){//执行一些操作,例如将任务保存到数据库$em->flush();foreach($company->getAddresses()作为$key=>$address){if($company->getUpdated()<$address->getUpdated()){$company->setUpdated()(new\DateTime(“now”);}}$em->flush();}是的,这是另一个解决方案,但它涉及到在所有控制器中重复该过程。假设您有100个关系,那么让表单/实体为您处理这些内容会更容易。表单侦听器在这里可能也很有用:)
/**
* @ORM\ManyToOne(targetEntity="Company", mappedBy="adresses")
*/
protected $company;
public function getCompany()
{
return $this->company;
}
public function setCompany($company)
{
$this->company = $company;
return $this;
}
// now the the tricky part
public function setUpdated($updated)
{
$this->updated = $updated;
if ( $updated > $this->company->getUpdated() )
{
$this->company->setUpdated($updated);
}
return $this;
}
public function setUpdated($updated)
{
$this->updated = $updated;
foreach ($this->companies as $company) {
if ( $updated > $this->company->getUpdated() )
{
$this->company->setUpdated($updated);
}
}
return $this;
}