2

我正在尝试使用 Symfony2 创建一个应用程序,但遇到了一些我无法弄清楚的事情。我有一个名为 Company 的实体和另一个名为 Address 的实体,具有多对多关系(应该是一对多,但我认为这是 Symfony/Doctrine 处理它的方式)。即每个公司可以有一个或多个地址。我已经设置了 Gedmo 的 Doctrine Extensions,并且我在两个实体上都使用了时间戳。我已经设置了一个更新两个链接实体的表单,但我真正想要的是能够在地址更新时为公司添加时间戳,因为它是两者的所有者。

有谁知道timestampable是否可以做到这一点或者我可能做错了什么?

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

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

Address 类,没什么可看的

<?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,但请告诉我

控制器

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())));
        }
    }    
}

将不胜感激任何帮助...

4

1 回答 1

1

我想时间戳不会检查关联实体的更改。

解决方案是在 Company 和 Address 之间创建双向的一对多关系,其中 Company 是拥有方。

公司

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

相应地调整你的映射注释,但我想你明白了......

于 2013-05-23T19:46:04.160 回答