1

次のようなフォーム選択フィールドを作成したいと思います。

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

値は問題ではなく、問題はラベルにあります。

productエンティティと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::getDetailsDoctrine\ORM\PersistentCollection「ProductDetails」エンティティではありません(コレクションは単一のオブジェクトではありません)。1対多/多対多の関係を利用して、製品が詳細に関連付けられていることを意味します。

次に、製品の詳細側からそれを試すことができます。

$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 に答える