2012-09-21 4 views
2

내가 심포니 2.1 교리 2.심포니 2 일 데이터베이스 행

내가 2 주 개체를 처리하고 있습니다를 사용하고 있습니다위한 여러 양식 필드. 데이터베이스에는 많은 기능이 있으며 테마별로 그룹화하는 기능은 Feature가 ManyToOne 관계가있는 FeatureCategory 엔터티와 관련되어 있습니다.

namespace Mv\PlaceBundle\Entity; 
… 

/** 
* Mv\PlaceBundle\Entity\Place 
* 
* @ORM\Table(name="place") 
* @ORM\Entity(repositoryClass="Mv\PlaceBundle\Entity\Repository\PlaceRepository") 
* @ORM\HasLifecycleCallbacks 
*/ 
class Place 
{ 
    /** 
    * @var integer $id 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

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

    /** 
    * @ORM\ManyToMany(targetEntity="\Mv\MainBundle\Entity\Feature") 
    * @ORM\JoinTable(name="places_features", 
    * joinColumns={@ORM\JoinColumn(name="place_id", referencedColumnName="id")}, 
    * inverseJoinColumns={@ORM\JoinColumn(name="feature_id", referencedColumnName="id")} 
    *) 
    */ 
    private $features; 

    /** 
    * Get id 
    * 
    * @return integer 
    */ 
    public function getId() 
    { 
    return $this->id; 
    } 

    /** 
    * Set name 
    * 
    * @param string $name 
    * @return Place 
    */ 
    public function setName($name) 
    { 
    $this->name = $name; 
    return $this; 
    } 

    /** 
    * Get name 
    * 
    * @return string 
    */ 
    public function getName() 
    { 
    return $this->name; 
    } 

    /** 
    * Add features 
    * 
    * @param \Mv\MainBundle\Entity\Feature $features 
    * @return Place 
    */ 
    public function addFeature(\Mv\MainBundle\Entity\Feature $features) 
    { 
    $this->features[] = $features; 
    echo 'Add "'.$features.'" - Total '.count($this->features).'<br />'; 
    return $this; 
    } 

    /** 
    * Remove features 
    * 
    * @param \Mv\MainBundle\Entity\Feature $features 
    */ 
    public function removeFeature(\Mv\MainBundle\Entity\Feature $features) 
    { 
    $this->features->removeElement($features); 
    } 

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

    public function __construct() 
    { 
    $this->features = new \Doctrine\Common\Collections\ArrayCollection(); 
    } 

기능 법인

장소 개체 : 여기에

는 다른 개체의 코드입니다

namespace Mv\MainBundle\Entity; 
… 

/** 
* @ORM\Entity 
* @ORM\Table(name="feature") 
* @ORM\HasLifecycleCallbacks 
*/ 
class Feature 
{ 
    use KrToolsTraits\PictureTrait; 

    /** 
    * @ORM\Id 
    * @ORM\Column(type="integer") 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    protected $id; 

    /** 
    * @ORM\Column(name="label", type="string", length=255) 
    * @Assert\NotBlank() 
    */ 
    protected $label; 

    /** 
    * @ORM\ManyToOne(targetEntity="\Mv\MainBundle\Entity\FeatureCategory", inversedBy="features", cascade={"persist"}) 
    * @ORM\JoinColumn(name="category_id", referencedColumnName="id") 
    */ 
    private $category; 

    /** 
    * Get id 
    * 
    * @return integer 
    */ 
    public function getId() 
    { 
     return $this->id; 
    } 

    /** 
    * Set label 
    * 
    * @param string $label 
    * @return Feature 
    */ 
    public function setLabel($label) 
    { 
     $this->label = $label; 
     return $this; 
    } 

    /** 
    * Get label 
    * 
    * @return string 
    */ 
    public function getLabel() 
    { 
     return $this->label; 
    } 

    /** 
    * Set category 
    * 
    * @param Mv\MainBundle\Entity\FeatureCategory $category 
    * @return Feature 
    */ 
    public function setCategory(\Mv\MainBundle\Entity\FeatureCategory $category = null) 
    { 
     $this->category = $category; 
     return $this; 
    } 

    /** 
    * Get category 
    * 
    * @return Mv\MainBundle\Entity\FeatureCategory 
    */ 
    public function getCategory() 
    { 
     return $this->category; 
    } 
} 

FeatureCategory 기업 :

namespace Mv\MainBundle\Entity; 
... 

/** 
* @ORM\Entity 
* @ORM\Table(name="feature_category") 
*/ 
class FeatureCategory 
{ 
    /** 
    * @ORM\Id 
    * @ORM\Column(type="integer") 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    protected $id; 

    /** 
    * @ORM\Column(name="code", type="string", length=255) 
    * @Assert\NotBlank() 
    */ 
    protected $code; 

    /** 
    * @ORM\Column(name="label", type="string", length=255) 
    * @Assert\NotBlank() 
    */ 
    protected $label; 

    /** 
    * @ORM\OneToMany(targetEntity="\Mv\MainBundle\Entity\Feature", mappedBy="category", cascade={"persist", "remove"}, orphanRemoval=true) 
    * @Assert\Valid() 
    */ 
    private $features; 

    public function __construct() 
    { 
     $this->features = new \Doctrine\Common\Collections\ArrayCollection(); 
    } 

    /** 
    * Get id 
    * 
    * @return integer 
    */ 
    public function getId() 
    { 
     return $this->id; 
    } 

    /** 
    * Set code 
    * 
    * @param string $code 
    * @return Feature 
    */ 
    public function setCode($code) 
    { 
     $this->code = $code; 
     return $this; 
    } 

    /** 
    * Get code 
    * 
    * @return string 
    */ 
    public function getCode() 
    { 
     return $this->code; 
    } 

    /** 
    * Set label 
    * 
    * @param string $label 
    * @return Feature 
    */ 
    public function setLabel($label) 
    { 
     $this->label = $label; 
     return $this; 
    } 

    /** 
    * Get label 
    * 
    * @return string 
    */ 
    public function getLabel() 
    { 
     return $this->label; 
    } 

    /** 
    * Add features 
    * 
    * @param \Mv\MainBundle\Entity\Feature $features 
    */ 
    public function addFeatures(\Mv\MainBundle\Entity\Feature $features){ 
     $features->setCategory($this); 
     $this->features[] = $features; 
    } 

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

    /* 
    * Set features 
    */ 
    public function setFeatures(\Doctrine\Common\Collections\Collection $features) 
    { 
     foreach ($features as $feature) 
     { 
     $feature->setCategory($this); 
     } 
     $this->features = $features; 
    } 

    /** 
    * Remove features 
    * 
    * @param Mv\MainBundle\Entity\Feature $features 
    */ 
    public function removeFeature(\Mv\MainBundle\Entity\Feature $features) 
    { 
     $this->features->removeElement($features); 
    } 

    /** 
    * Add features 
    * 
    * @param Mv\MainBundle\Entity\Feature $features 
    * @return FeatureCategory 
    */ 
    public function addFeature(\Mv\MainBundle\Entity\Feature $features) 
    { 
     $features->setCategory($this); 
     $this->features[] = $features; 
    } 
} 

기능 표가 이미 채워져 있으며 사용자가 지형지 물을 추가 할 수 없으며 지형지 물을 지형지 물에 연결하기 위해 지형지 물을 추가 할 수 없습니다. (Feature 엔터티는 현재 Places에만 링크되어 있지만 나중에 내 응용 프로그램의 다른 엔터티와 관련되며 모든 엔터티에서 사용할 수있는 모든 기능을 포함합니다)

장소 양식에서 다음과 같은 확인란을 표시해야합니다. 장소에 사용할 수있는 기능은 있지만 범주별로 그룹화하여 표시해야합니다. 예 :

방문 (FeatureCategory - 코드 VIS) :

  • 무료 (기능)
  • 지불 (기능)

구사 가능 언어 (FeatureCategory - 코드 LAN) :

  • 영어 (기능)
  • 프랑스어 (기능)
  • 스페인어 (기능)

내 생각

사용이처럼 내 PlaceType 형태의 가상 형태 :

$builder 
    ->add('name') 
    ->add('visit', new FeatureType('VIS'), array(
     'data_class' => 'Mv\PlaceBundle\Entity\Place' 
    )) 
    ->add('language', new FeatureType('LAN'), array(
     'data_class' => 'Mv\PlaceBundle\Entity\Place' 
    )); 

그리고를 만들 FeatureType 가상 양식 (예 :

)
class FeatureType extends AbstractType 
    { 
     protected $codeCat; 

     public function __construct($codeCat) 
     { 
      $this->codeCat = $codeCat; 
     } 

     public function buildForm(FormBuilderInterface $builder, array $options) 
     { 
      $builder 
       ->add('features', 'entity', array(
        'class' => 'MvMainBundle:Feature', 
        'query_builder' => function(EntityRepository $er) 
        { 
         return $er->createQueryBuilder('f') 
           ->leftJoin('f.category', 'c') 
           ->andWhere('c.code = :codeCat') 
           ->setParameter('codeCat', $this->codeCat) 
           ->orderBy('f.position', 'ASC'); 
        }, 
        'expanded' => true, 
        'multiple' => true 
       )); 
     } 

     public function setDefaultOptions(OptionsResolverInterface $resolver) 
     { 
      $resolver->setDefaults(array(
       'virtual' => true 
      )); 
     } 

     public function getName() 
     { 
      return 'features'; 
     } 
    } 

이 솔루션을 사용하면 원하는 바를 얻을 수 있지만 바인드 프로세스가 모든 기능을 유지하지는 못합니다. 그것들을 그룹화하는 대신에, 그것은 단지 나를 유지하고 마지막 그룹 인 "언어"를 유지하고 모든 이전 기능 데이터를 지 웁니다. 이 동작을 보시려면 5 개의 체크 박스를 체크하면 Place-> addFeature() 함수에 5 회 잘 도착하지만 featuresCollection의 길이는 1, 2, 1, 2, 3입니다.

다른 방법으로하는 방법에 대한 아이디어가 있습니까? 모델을 변경해야한다면 여전히 할 수 있습니다. Feature와 관련된 미래의 다른 엔터티에서 재사용 할 수있는 가장 좋은 방법은 무엇입니까?

감사합니다.

답변

0

나는 원래의 필요성이에 대해서 에 불과하다고 생각합니다.

그래서 원하는 자동 생성 양식을 얻으려면 양식 및 엔티티 지속성 로직을 조정하면 안됩니다.

당신은 기본적인 형태

$builder 
    ->add('name') 
    ->add('features', 'entity', array(
     'class' => 'MvMainBundle:Feature', 
     'query_builder' => function(EntityRepository $er) { 
       return $er->createQueryBuilder('f') 
       //order by category.xxx, f.position 
      }, 
       'expanded' => true, 
       'multiple' => true 
      )); 

로 다시 이동하여 form.html.twig을 조정할해야