我想创建一个表单选择字段,如下所示:
<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使用正确的语言。
那么,有人可以通过加入查询帮助我制作我想要的选择列表吗?
答案 0 :(得分: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');
}
)
);
答案 1 :(得分:1)
我终于设法让这个工作了。下面,我正在展示我是如何做到这一点的,以防其他人遇到同样的问题。
我现在正在使用自定义表单类型。
在setDefaultOptions中,我调用的是一个存储库方法,它返回一个带有“product_id”=&gt;的数组。 “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-&gt; repository-&gt; 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'作为表单类型。
我不确定这是否是最好的方法,但至少它是有效的。
现在我只需要弄清楚如何将用户的当前语言传递给存储库,但这是以后的问题。