2016-01-21 39 views
0

我正在開發一個網上商店系統,目前我在管理工具上工作。我有4個相關的實體Symfony2表單類型嵌套太多查詢

  • 文章
    • 存儲主要文章數據(名稱,描述)
  • ArticleSuppliers
    • 存儲數據的變體(articleNumber,價格..)
  • ArticleAttributesValue s
    • 存儲每個變體的值(例如,紅40釐米)
  • ArticleAttributes
    • 商店屬性(顏色,高度的名字......)

因爲它更容易編輯一個產品,我想將正在工作的表格合併在一起。

ArticlesType結合ArticleSuppliersType結合ArticleAttributesValuesType

我FormType:ArticleAttributesValues包含一個實體的選擇ArticleAttributes

這是工作!但是有一個巨大的問題。我顯示每個變體的屬性,因此每個屬性都有一個查詢(想象一下具有20個變體和10個屬性的產品)。

解決方案很簡單:我只需要給我的FormType提供一個attributeNames + id數組,但我不知道這是如何完成的。

但我會感激所有其他解決方案。

預先感謝您!

編輯:

我會嘗試用代碼來解釋我的問題:

// controller 
$article = $em->getRepository('MyBundle:Articles')->find($id); 

$form = $this->createForm(new ArticleType(), $article); 

這是我的文章類型:

// articleType 
    $builder->add('shortName', 'text', 
       array('label' => false)) 
      ->add('shortDescription', 'text', 
       array('label' => false)) 
      ->add('longDescription', 'textarea', 
       array('label' => false)) 
      ->add('variants', 'collection', array('type' => new VariantsType())) 
      ->add('save', 'submit', array('label' => 'Save')); 

這涉及到VariantsType:

// variantsType 
    $builder->add('supplierArticleNumber', 'text', 
       array('label' => false)) 
      ->add('price', 'text', 
       array('label' => false)) 
      ->add('variantvalues', 'collection', array('type' => new VariantsvaluesType())); 

這涉及到VariantsvaluesType,其中我的選擇字段是。

// variantsvaluesType 
    $builder->add('attributeValue', 'text', 
       array('label' => false)) 
      ->add('attributeUnit', 'text', 
       array('label' => false, 'required' => false)) 
      ->add('attrName', 'entity', array(
       'class' => 'MyBundle:ArticleAttributes', 
       'property' => 'attributeName', 
      )); 

這種選擇字段是相同的(當然也有時有變化),所以這將是不必要的查詢它X倍...

我的想法是加載所有attributeNames在我的控制器並通過$選項將它傳遞給variantsvaluesType,但是這是不工作...

+0

你想要傳遞一個數組到表單類型嗎? – Dheeraj

+0

@dheeraj是的,但不是第一級表單類型。我必須將它傳遞給嵌套窗體類型的另一個嵌套窗體類型 – RoyRobsen

+0

我可能不理解這個問題。由於延遲加載,查詢本身是否會減慢速度?如果是這樣,那就讓自己定製一個查詢,然後加入你知道需要的各種實體。 – Cerad

回答

0

我明白了,那也許是因爲你可以嘗試下想法。使用get函數爲每個要加載的集合創建一個服務,然後在服務的構造函數中,只能加載所有列表一次。然後,您可以在需要的地方使用該服務。它必須像單身人士一樣工作。不便之處在於所有這些列表都應該一直在內存中加載,但沒有任何內容是免費的。會不會是這樣的:

use Doctrine\ORM\EntityManager; 

class CollectionsService 
{ 
    private $em; 

    private $collectionOne; 

    private $collectionTwo; 

    public function __construct(EntityManager $entityManager) 
    { 
     $this->em = $entityManager; 
     $this->collectionOne= $this->em->getRepository('AppBundle:CollectionOne')->findAll(); 
     $this->collectionTwo= $this->em->getRepository('AppBundle:CollectionTwo')->findAll(); 
    } 

    public function getCollectionOne(){ 
     return $this->collectionOne; 
    } 

    public function getCollectionTwo(){ 
     return $this->collectionTwo; 
    } 

} 

還必須努力在像下一個功能的東西,也沒有必要做在構造函數中的負載。

public function getCollectionOne(){ 
    if($this->collectionOne == null){ 
     $this->collectionOne= $this->em->getRepository('AppBundle:CollectionOne')->findAll(); 
    } 
    return $this->collectionOne; 
} 

然後揭露類作爲服務services.yml

parameters: 
    collection.controller: AppBundle\Services\CollectionsService 

services: 
    collections.service: 
      class: "%collection.controller%" 
      arguments: 
        entityManager: "@doctrine.orm.entity_manager" 

最後只使用該服務在控制器或形式來更新數據$options['data']

$collectionOne = $this->get('collections.service')->getCollectionOne(); 

我希望這對你有所幫助。