Symfony2时间戳包括相关实体的更新 [英] Symfony2 timestampable include update of related entity

查看:125
本文介绍了Symfony2时间戳包括相关实体的更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Symfony2创建一个应用程序,而且我反对我无法想象的事情。我有一个叫做公司的实体,另一个叫做Address,具有多对多关系(应该是一对多,但我认为这是Symfony / Doctrine处理它的方式)。即每个公司都可以有一个或多个地址。我已经设置了Gedmo的教义扩展,我在两个实体上都使用timestampable。我已经设置了更新两个链接实体的表单,但是如果地址更新,那么我真正希望能够对公司进行时间戳记,因为它是两者的所有者。

I'm trying to create an application using Symfony2, and I've come up against something I can't figure out. I have an entity called Company and another called Address, with a Many to Many relationship (should be One to Many but I think this is the way Symfony/Doctrine handles it). i.e. each Company could have one or more Addresses. I have set up the Gedmo's Doctrine Extensions and I'm using timestampable on both entities. I have set up a form which updates both linked entities, but what I would really like is to be able to timestamp Company if Address gets updated, as it is the owner of the two.

有谁知道时间戳可以做到这一点还是我可能做错了?

Does anyone know if timestampable can do this or what I may have done wrong?

你可以看到我的公司类在这里:

You can see my Company class here:

<?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;

地址类,不太可观看

<?php
// src/Amber/AtsBundle/Entity/Address.php
namespace Amber\AtsBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;

/**
 * Address
 *
 * @ORM\Table()
 * @ORM\Entity
 */
class Address
{
/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
 private $id;

/**
 * @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;

我不认为你需要看到setter和getter,但让我知道

I don't think you need to see setters and getters but let me know

控制器

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class CompaniesController extends Controller
{

    public function editAction(Request $request, $companyID)
    {
    $em = $this->getDoctrine()->getManager();
    $company = $em->getRepository('AmberAtsBundle:Company')->find($companyID);

    $passExist = 'Yes';

   $form = $this->createForm(new CompanyType(), $company, array("pass_exists" => $passExist));

    if ($request->isMethod('POST')) {
        $form->bind($request);

        if ($form->isValid()) {
            $em->flush(); 

            return $this->redirect($this->generateUrl('amber_ats_companies_edit', array('companyID' => $company->getId())));
        }
    }    
}

感谢任何帮助...

推荐答案

我认为timestample不检查关联的实体的变化。

I suppose timestample does not check for changes on associated entites.

解决方案是在公司与公司之间建立双向的一对多关系。公司是自己的一方。

The solution is to create a bi-directional one-to-many relation between Company and Address with Company being the owning side.

公司

/** 
 * @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;
}

如果多个公司可以拥有相同的地址,您可以使用多对多并循环遍历所有关联公司,如下所示:

You can use many-to-many if multiple companies can have the same addresses and loop over all associated companies like this:

public function setUpdated($updated)
{
    $this->updated = $updated;
    foreach ($this->companies as $company) {
       if  ( $updated > $this->company->getUpdated() )
       {
           $this->company->setUpdated($updated);
        }
    }

    return $this;
}

相应地调整映射注释,但我想你得到的想法...

Adjust your mapping annotations accordingly but i guess you get the idea ...

这篇关于Symfony2时间戳包括相关实体的更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆