2017-03-28 6 views
11

parentのアクションを開発していますが、これはユーザー入力によって与えられた子をいくつか追加する必要があります。まだ存在していない場合のみ、親に子オブジェクトを追加する

子供は3つのプロパティを持ち、それらを組み合わせると、それぞれの子供は常に一意でなければなりません。

私はsymfonyのと教義と私の基本的な親クラスを利用するには、次のようになります。

class Parent 
{ 
    /** 
    * @var Child[]|ArrayCollection 
    * 
    * @ORM\OneToMany(targetEntity="Child", mappedBy="parent") 
    * @ORM\OrderBy({"dateCreated": "DESC"}) 
    */ 
    private $childs; 

    /** 
    * Add child 
    * 
    * @param \AppBundle\Entity\Child $child 
    * 
    * @return Parent 
    */ 
    public function addChild(\AppBundle\Entity\Child $child) 
    { 
     $this->childs[] = $child; 
     $child->setParent($this); 
     return $this; 
    } 

    /** 
    * Remove child 
    * 
    * @param \AppBundle\Entity\Child $child 
    */ 
    public function removeChild(\AppBundle\Entity\Child $child) 
    { 
     $this->childs->removeElement($child); 
    } 

    /** 
    * Get childs 
    * 
    * @return \Doctrine\Common\Collections\Collection 
    */ 
    public function getChilds() 
    { 
     return $this->childs; 
    } 
} 

このような私の子供のクラスを見て(再び本当に基本):次に

class Child 
{ 
    /** 
    * @var int 
    * 
    * @ORM\Column(name="cupboard", type="integer") 
    */ 
    private $cupboard; 

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

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

    /** 
    * @var Parent 
    * 
    * @ORM\ManyToOne(targetEntity="Parent", inversedBy="childs") 
    * @ORM\JoinColumns({ 
    * @ORM\JoinColumn(name="parent_id", referencedColumnName="id") 
    * }) 
    */ 
    private $parent; 

    /** 
    * Set cupboard 
    * 
    * @param string $cupboard 
    * 
    * @return Child 
    */ 
    public function setCupboard($cupboard) 
    { 
     $this->cupboard = $cupboard; 

     return $this; 
    } 

    /** 
    * Get cupboard 
    * 
    * @return int 
    */ 
    public function getCupboard() 
    { 
     return $this->cupboard; 
    } 

    /** 
    * Set shelf 
    * 
    * @param string $shelf 
    * 
    * @return Child 
    */ 
    public function setShelf($shelf) 
    { 
     $this->shelf = $shelf; 

     return $this; 
    } 

    /** 
    * Get shelf 
    * 
    * @return int 
    */ 
    public function getShelf() 
    { 
     return $this->shelf; 
    } 

    /** 
    * Set item 
    * 
    * @param string $item 
    * 
    * @return Child 
    */ 
    public function setItem($item) 
    { 
     $this->item = $item; 

     return $this; 
    } 

    /** 
    * Get item 
    * 
    * @return int 
    */ 
    public function getItem() 
    { 
     return $this->item; 
    } 

    /** 
    * Set parent 
    * 
    * @param Parent $parent 
    * 
    * @return Child 
    */ 
    public function setParent(Parent $parent) 
    { 
     $this->parent = $parent; 

     return $this; 
    } 

    /** 
    * Get parent 
    * 
    * @return Parent 
    */ 
    public function getParent() 
    { 
     return $this->parent; 
    } 
} 

私が持っていますそれに対応する子を作成しなければならないparentオブジェクト(編集アクションと同じ種類)ごとのアクションです。私は(特定の親のための)リンクをクリックすると、フォームは、三つの入力フィールドがあるように生成されます。

  • 食器棚を
  • 項目の棚
  • 数が

ユーザーが指定する必要があります

  • 整数でどのくらいの数のアイテムをどの食器棚に追加したいのか、どの棚に追加したいのですか?アイテム(整数)が既にその棚にある所定の食器棚に存在する場合は、それを再度作成すべきではありませんが、最初に利用可能な整数がアイテムに使用されます。

    どうすれば簡単にすることができますか?私はParentクラスのaddChild関数を使用することができますが、わかりません。

    私がこれまで試したのは、アレイを作成し、すべてのアイテムを食器棚と棚に沿ってグループ化し、アイテムがその配列に存在しない場合は作成することです。

    これは私のコードです:余分な情報については

    public function addItemAction(Request $request, $id = null){ 
        $parent = $this->admin->getSubject(); 
    
        if (!$parent) { 
         throw new NotFoundHttpException(sprintf('Unable to find the object with id: %s', $id)); 
        } 
    
        $em = $this->getDoctrine()->getManager(); 
    
        $form = $this->createForm(AddItemType::class); 
        $form->handleRequest($request); 
    
        if ($form->isSubmitted() && $form->isValid()) { 
         $kids = $popUnit->getChilds(); 
         $formParams = $request->request->get('add_item'); 
    
         $units = array(); 
         foreach ($kids as $kid) { 
          $units[$kid->getCupboard()][$kid->getShelf()][$kid->getItem()] = $kid->getItem(); 
         } 
    
         $givenShelf = $units[$formParams['cupboard']][$formParams['shelf']]; 
    
         for ($i = 1; $i <= $formParams['itemAmount']; $i++) { 
          if (!in_array($i, $givenShelf)) { 
           $child = new Child(); 
           $child->setParent($parent); 
           $child->setCupboard($formParams['cupboard']); 
           $child->setShelf($formParams['shelf']); 
           $child->setItem($i); 
    
           $em->persist($child); 
           $em->flush(); 
          } 
         } 
         return new RedirectResponse($this->admin->generateUrl('show', array('id' => $parent->getId()))); 
        } 
    
        return $this->render('AppBundle:Parent:add_childs.html.twig', array(
         'form' => $form->createView(), 
         'parent' =>$parent, 
        )); 
    } 
    

    、これは私のフォームビルダがどのように見えるかです:

    public function buildForm(FormBuilderInterface $builder, array $options) { 
        $builder 
         ->add('cupboard', NumberType::class) 
         ->add('shelf', NumberType::class) 
         ->add('itemAmount', NumberType::class, array('label' => 'Number of Items')) 
        ; 
    } 
    

    どのようにして作ることが事実と可能な限り、このアクションは同じくらい簡単にすることができます親の食器棚にある棚には、一意のアイテムだけが追加されていることを確認してください。私はプロパティやクラスを変更することはできません。私はこれと一緒に作業しなければならない。リスナーやその他の関数を作成するなど、他の複雑な方法を使用する必要はありません。

    私は自分の状況をうまく説明してくれることを願っています。誰かが良いフィードバックで私を助けてくれることを願っています。

  • 答えて

    4

    あなたは、このようなParentクラスのaddChild機能を変更することができることを正しい:

    /** 
        * Add child 
        * 
        * @param \AppBundle\Entity\Child $child 
        * 
        * @return Parent 
        */ 
        public function addChild(Child $child) 
        { 
         if (! is_array($this->childs) || ! in_array($child, $this->childs)) { 
          $this->childs[] = $child; 
          $child->setParent($this); 
         } 
         return $this; 
        } 
    

    この条件だけでは子がまだ存在しない場合は、子がまだない場合、子を追加したり、と述べています$this->childs配列内に追加します。

    +1

    私の知る限り、in_array関数はオブジェクトを比較できません – michelek

    1

    あなたはDoctrineのコレクションとしてremoveChild経由$childsにアクセスするので:

    /** 
    * Remove child 
    * 
    * @param \AppBundle\Entity\Child $child 
    */ 
    public function removeChild(\AppBundle\Entity\Child $child) 
    { 
        $this->childs->removeElement($child); 
    } 
    

    ので、コンストラクタでは、あなたが最初にあなたのお子様のコレクションを初期化する必要があります。

    public function __construct() 
    { 
        $this->childs = new ArrayCollection(); 
    } 
    

    子供が重複しないようにするには、コレクションに追加する前に既存のものを確認する必要があります。

    /** 
    * Add child 
    * 
    * @param \AppBundle\Entity\Child $child 
    * 
    * @return Parent 
    */ 
    public function addChild(\AppBundle\Entity\Child $child) 
    { 
        if (!$this->childs->contains($child)) { 
         $this->childs->add($child); 
         $child->setParent($this); 
        } 
    
        return $this; 
    } 
    
    関連する問題