1

我想创建一个如下所示的表单选择字段:

<select>
<option value="product.product_id">product_details.detail_name</option>
etc...
</select>

值不是问题,问题在于标签。

我有一个产品实体和一个 productDetails 实体,其中包含有关产品的翻译数据。

所以,在我的表单类型类中,在 buildForm 方法中,我有这个:

    $builder->add('product', 'entity', array(
        'class' => 'MyBundle:Product',
        'property' => 'details.detail_name',
        'query_builder' => function(EntityRepository $er) {
            return $er->createQueryBuilder('p')
                ->select('p, pd')
                ->join('p.details', 'pd')
                ->where('pd.language_id = :lang')
                ->setParameter('lang', 'en');
        }));

我希望属性是 details.detail_name。

我为此属性值尝试了不同的值。像“details.detail_name”、“pd.detail_name”和“p.details.detail_name”。

但似乎不可能让属性显示详细信息名称。

当我使用上述代码时,我收到此错误:

Neither property "detail_name" nor method "getDetailName()" nor method "isDetailName()" exists in class "Doctrine\ORM\PersistentCollection"

这个 getDetailName() 方法确实存在于 ProductDetails 实体中,我检查了这些实体,它们似乎都没有问题。此外,当我在表单之外使用这些实体时,它们也能正常工作。

我还尝试直接在我的数据库上执行结果查询,它给了我预期的结果。detail_name 使用正确的语言。

那么,有人可以帮助我如何通过连接查询制作我想要的选择列表吗?

4

2 回答 2

2

我终于设法让这个工作。下面,我将展示我是如何做到这一点的,以防其他人遇到同样的问题。

我现在正在使用自定义表单类型。

在 setDefaultOptions 中,我调用了一个存储库方法,它返回一个带有“product_id”=>“detail_name”的数组。

class ProductChoiceType extends AbstractType
{
    private $repository;

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

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
                'choices' => $this->repository->findAllProductsForForm('nl', true)
            ));
    }

    public function getParent()
    {
        return 'choice';
    }

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

在 $this->repository->findAllProductsForForm 方法中,我使用查询和 foreach 循环使数组适合选择列表。

然后,我必须在我的 services.xml 文件中注册存储库和此类型:

<service id="mybundle.repository.product"
         factory-service="doctrine.orm.default_entity_manager"
         factory-method="getRepository"
         class="MyBundle\Repository\ProductRepository" >
    <argument>MyBundle:Product</argument> <!-- not sure why I need this, but it wouldn't work without it -->
</service>

<service id="mybundle.xxx.form.product_choice_type" class="Mybundle\Form\Type\ProductChoiceType">
    <argument type="service" id="mybundle.repository.product" />
    <tag name="form.type" alias="product_choice" />
</service>

然后,在根表单类型(我认为它被称为)中,我使用“product_choice”作为表单类型。

我不确定这是否是最好的方法,但至少它有效。

现在我只需要弄清楚如何将用户的当前语言传递到存储库,但这是以后的问题。

于 2013-01-07T15:08:17.777 回答
1

从我看到的你的方法Product::getDetails返回Doctrine\ORM\PersistentCollection不是“ProductDetails”实体(所以集合不是单个对象)。这意味着产品使用一对多/多对多关联与细节相关。

您可以尝试从产品详细信息方面进行操作:

$builder->add(
    'product',
    'entity',
    array(
        'class' => 'MyBundle:ProductDetails',
        'property' => 'detail_name',
        'query_builder' => function(EntityRepository $er) {
            return $er->createQueryBuilder('pd')
                ->select('pd, p')
                ->join('pd.product', 'p')
                ->where('pd.language_id = :lang')
                ->setParameter('lang', 'en');
         }
    )

);
于 2013-01-05T14:45:23.520 回答