Symfony2表单类型嵌套了太多查询

时间:2016-01-21 12:32:12

标签: forms symfony types entity choice

我正在开发一个网上商店系统,目前我正在使用管理工具。我有4个相关实体

  • 文章
    • 存储主要文章数据(名称,描述)
  • ArticleSuppliers
    • 存储变体数据(articleNumber,price ..)
  • ArticleAttributesValues
    • 存储每个变体的属性(值,例如红色,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并通过 $ options 将其传递给 variantsvaluesType ,但这不起作用...

1 个答案:

答案 0 :(得分: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();

我希望这对你有所帮助。