2017-07-05 61 views
0

我有一個錯誤,當我嘗試堅持一個數據的所有數據,我沒有找到關於有別人完全一樣的問題,幫助....一份堅持從插入一對多ArrayCollection的變量

我有兩個連接實體得分(多對一)/ 球員(一對多),當我堅持的得分,學說將儲存在對應我想存儲得分球員的陣列收集$分數的所有得分。 有關信息,我存儲了一輪的每個分數,因此用戶有多個分數(所以manyToOne/OneToMany關係)。

我有一個玩家的列表和他們所有的分數。我只想插入最後一個,就像其他人已經在數據庫中一樣。但對於我嘗試過的每種解決方案,教條都會插入所有分數......即使我只將最後一個分數放在玩家分數中。 然後,我刪除每個實體堅持級聯,學說拋出一個異常有關實體的鏈接...

這裏是分數實體

/** 
* Score 
* 
* @ORM\Table(name="score") 
* @ORM\Entity(repositoryClass="AppBundle\Entity\Repository\ScoreRepository") 
*/ 
class Score 
{ 
/** 
* @var int 
* 
* @ORM\Column(name="id", type="integer") 
* @ORM\Id 
* @ORM\GeneratedValue(strategy="AUTO") 
*/ 
protected $id; 

/** 
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Player", inversedBy="scores", cascade={"persist"}) 
* @ORM\JoinColumn(name="player", referencedColumnName="id") 
* 
* @var Player 
*/ 
private $player; 

/** 
* @var DateTime 
* 
* @ORM\Column(name="played_at", type="datetime") 
*/ 
private $playedAt; 

/** 
* @var int 
* 
* @ORM\Column(name="value", type="integer") 
*/ 
private $value; 

這裏是玩家的實體:

/** 
* Player 
* 
* @ORM\Table(name="player") 
* @ORM\Entity(repositoryClass="AppBundle\Entity\Repository\PlayerRepository") 
*/ 
class Player extends BaseUser 
{ 
/** 
* @var int 
* 
* @ORM\Column(name="id", type="integer") 
* @ORM\Id 
* @ORM\GeneratedValue(strategy="AUTO") 
*/ 
protected $id; 

/** 
* @var string 
* 
* @ORM\Column(name="firstname", type="string", length=255) 
*/ 
private $firstname; 

/** 
* @var string 
* 
* @ORM\Column(name="lastname", type="string", length=255) 
*/ 
private $lastname; 

/** 
* @var string 
* 
* @ORM\Column(name="job", type="string", length=255) 
*/ 
private $job; 

/** 
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Score", mappedBy="player", cascade={"persist"}) 
* 
* @var ArrayCollection|Score[] 
*/ 
private $scores; 

這裏是現在,我的控制,我想堅持比分

$content = $request->getContent(); 
    $scoresParams = []; 
    if (!empty($content)) 
    { 
     $scoresParams = json_decode($content, true); // 2nd param to get as array 
    } 
    $players = array(); 

    $transformer = $this->get('app.transformer.score'); 
    foreach($scoresParams as $k=>$v) { 
     $players[] = $transformer->reverseTransform($v); 
    } 
    foreach($players as $k=>$p) { 
     $index = count($p->getScores()) - 1; 
     $s = $p->getScores()[$index]; 
     $p->setScores(array($s)); 
     $this->get('app.repository.score')->persist($s); 
    } 

我只用我想保存的分數來設置玩家得分...因爲,就像我有一個堅持在cascad上,並且所有其他用戶的分數都不是從教義中檢索,hit會嘗試插入它們... 因此,對於第一個玩家來說,沒問題,但是第二個玩家,當我堅持它的時候,$ s已經有了一個ID,並且它堅持了玩家的所有數據(不僅是最後一個)。

變壓器是一個束(聯賽\分形\變壓器),從數據

public function reverseTransform(array $data) 
{ 
    $this->checkRequiredFields($data); 

    $player = $this->playerRepository->find($data[self::KEY_ID]); 

    if (!$player) { 
     throw new NotFoundException('User not found'); 
    } 

    $scoresRaw = $data[self::KEY_ENC_SCORES]; 
    $scores = array(); 

    foreach($scoresRaw as $k => $s) { 
     $score = new Score($player); 
     if($s[self::KEY_ENC_SCORE_ID] != 0) { 
      $score->setId($s[self::KEY_ENC_SCORE_ID]); 
     } 
     $score->setPlayedAt((new \DateTime())->setTimestamp($s[self::KEY_ENC_SCORE_DATE])); 
     $score->setValue($s[self::KEY_ENC_SCORE_VALUE]); 
     $scores[] = $score; 
    } 

    $player->setScores($scores); 

    return $player; 
} 

的陣列創建的玩家的數組你可以看到什麼是錯在這裏?


下面是解 - >控制器

 $content = $request->getContent(); 
    $scoresParams = []; 
    if (!empty($content)) 
    { 
     $scoresParams = json_decode($content, true); // 2nd param to get as array 
    } 
    $players = array(); 

    $transformer = $this->get('app.transformer.score'); 
    // For each players 
    foreach($scoresParams as $i=>$player) { 
     $scores = $player['scores']; 
     foreach($scores as $j=>$s) { 
      $score = $transformer->reverseTransform($s['data']); 
      $this->get('app.repository.score')->merge($score); 
     } 
    } 

    $response = new JsonResponse(array('data' => '')); 
    $response->setStatusCode(201); 

    return $response; 

而且該得分陣列相反的對象

$player = $this->playerRepository->find($data[self::KEY_USER]); 

    if (!$player) { 
     throw new NotFoundException('User not found'); 
    } 

    $score = new Score($player); 
    if($data[self::KEY_ID] != 0) { 
     $score->setId($data[self::KEY_ID]); 
    } 
    $score->setPlayedAt((new \DateTime())->setTimestamp($data[self::KEY_DATE])); 
    $score->setValue($data[self::KEY_VALUE]); 

    return $score; 
+1

我建議你命名你更好的變量,它還挺硬代碼^^'$分數= $球員[ '分數']來獲得;' - >'$ playerScores' 。在你的foreach中:'foreach($ scoresParams as $ scoreParam)'(你不用你的密鑰)。不要把它當作個人,我真的認爲當你回到你的代碼時你會以這種方式獲得很多時間。 – goto

回答

1

作爲你的實體來自一個JSON的功能,它是沒有鏈接到實體經理。

我認爲你應該使用merge()方法來鏈接它。

http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/working-with-objects.html#merging-entities

$score->setValue($s[self::KEY_ENC_SCORE_VALUE]); 
    $this->get('app.repository.score')->merge($score); 
    $scores[] = $score; 
} 
$player->setScores($scores); 
+0

我已經在控制器(而不是堅持)嘗試過這一點,並且這有相同的結果... 主義存儲新的比分和球員的所有比分。 這就是我的想法,但刪除用戶的所有分數,只把最後一個我想要的,不會改變......看來,學說檢索所有的分數,並嘗試重新插入它們... – QuentinG

+0

好吧現在,您的解決方案很好。 我不得不重寫源代碼,觀點更注重分數而不是用戶。 我會更新我的問題,以解決方案 – QuentinG