私のSymfony2プロジェクトには、ユーザーとお気に入りの2つの関連エンティティがあります。彼らは多対多の関係を持っています。
私のアプリケーションは次のように機能します。Twigページには、[お気に入りに追加]ボタンのあるアイテムがいくつかあります。ボタンをクリックすると、コントローラーはitem_idを[お気に入り]列に保存します。しかし、アイテムをお気に入りに追加したユーザーを保存したいのですが、ここでアプリケーションが失敗します。
ユーザーとお気に入りは存在しますが、ユーザーとお気に入りの間の結合列は空のままです。また、エラーは発生しません。
これが私のコードです:
エンティティユーザー
class Users implements AdvancedUserInterface
{
/**
* @var \Doctrine\Common\Collections\ArrayCollection
*
* @ORM\ManyToMany(targetEntity="Favorites", inversedBy="user", cascade={"persist"})
* @ORM\JoinTable(name="user_has_favorite",
* joinColumns={
* @ORM\JoinColumn(name="user_id", referencedColumnName="user_id")
* },
* inverseJoinColumns={
* @ORM\JoinColumn(name="favorite_id", referencedColumnName="favorite_id")
* }
* )
*/
private $favorite;
public function __construct()
{
$this->favorite = new \Doctrine\Common\Collections\ArrayCollection();
}
public function addFavorite(\Geo\CityTroopersBundle\Entity\Favorites $favorite)
{
$this->favorite[] = $favorite;
return $this;
}
...
エンティティのお気に入り
class Favorites
{
/**
* @var \Doctrine\Common\Collections\ArrayCollection
*
* @ORM\ManyToMany(targetEntity="Users", mappedBy="favorite", cascade={"persist"})
*/
private $user;
public function __construct()
{
$this->user = new \Doctrine\Common\Collections\ArrayCollection();
}
public function addUser(\Geo\CityTroopersBundle\Entity\Users $user)
{
$this->user[] = $user;
return $this;
}
私のコントローラー
public function showNewsAction()
{
$request = $this->get('request');
$itemId=$request->request->get('itemId');
if($itemId != NULL)
{
//MAKE NEW FAVORITE AND ADD TO DATABASE LINKED WITH ITEM
$favorite = new Favorites();
$favorite->setItemId($itemId);
//LINK FAVORITE ID WITH USER ID IN JOINCOLUMN
$userId = 6;
$em = $this->getDoctrine()->getEntityManager();
$user = $em->getRepository('GeoCityTroopersBundle:Users')->find($userId);
$favorite->addUser($user);
$em->persist($favorite);
//I TRIED THIS TOO, BUT IT FAILED
/*$user->addFavorite($favorite);
$em->persist($user);*/
$em->flush();
あなたはそこに近かった。 doctrine多対多の関係の場合、両方のaddメソッドを呼び出す必要があります
$favorite->addUser($user);
$user->addFavorite($favorite);
$em->persist($favorite);
$em->persist($user);
$em->flush();
これでうまくいくはずです。 docs でこれを行いますが、あまり明示的に言及しないでください。多くの人がこれに遭遇するので(私自身も含めて)、理由もわかりません。
ここで説明するように、接続管理は所有側のみが担当します: http://doctrine-orm.readthedocs.org/en/latest/reference/association-mapping.html#owning-and-inverse-side -on-a-manytomany-association
だからだけ
$user->addFavorite($favorite);
持続するべきであり、
$favorite->addUser($user);
あなたのラインで:
@ORM\JoinColumn(name="favorite_id", referencedColumnName="favorite_id")
ザ・
name="favorite_id"
一部は結合テーブルの列を参照しますが、
referencedColumnName="favorite_id"
通常は単に「id」であるお気に入りのテーブルのIDを指します。試してみてください :
/**
* @var \Doctrine\Common\Collections\ArrayCollection
*
* @ORM\ManyToMany(targetEntity="Favorites", inversedBy="user", cascade={"persist"})
* @ORM\JoinTable(name="user_has_favorite",
* joinColumns={
* @ORM\JoinColumn(name="user_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* @ORM\JoinColumn(name="favorite_id", referencedColumnName="id")
* }
* )
*/
private $favorite;
セドリックが示したように、多対多の関係のレコードの追加は一方向でのみ行われ、関係の定義方法によって異なります。追加は関係の親エンティティによってのみ実行できるため、この場合は:
$user->addFavorite($favorite);