2

Symfony2 を使用してアプリケーションを作成しようとしていますが、理解できない問題に遭遇しました。Company と呼ばれるエンティティと Address と呼ばれる別のエンティティがあり、多対多の関係があります (1 対多である必要がありますが、これが Symfony/Doctrine の処理方法だと思います)。つまり、各会社は 1 つまたは複数のアドレスを持つことができます。Gedmo の Doctrine Extensions をセットアップし、両方のエンティティでタイムスタンプを使用しています。リンクされた両方のエンティティを更新するフォームを設定しましたが、アドレスが更新された場合に会社にタイムスタンプを付けることができるようにしたいと考えています。これは 2 つの所有者であるためです。

タイムスタンプがこれを行うことができるかどうか、または私が間違ったことをした可能性があるかどうかは誰にもわかりますか?

ここで私の会社のクラスを見ることができます:

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

セッターとゲッターを見る必要はないと思いますが、教えてください

コントローラ

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 の間に双方向の 1 対多の関係を作成し、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 に答える