Symfony2 と Doctrine2 で E コマース バンドルを作成しています。製品の機能にはEAVアプローチを適用し、無制限の機能には製品の価値を適用しています。このために、Product、FeatureKind、FeatureValues という 3 つの基本エンティティがあります。
- FeatureKind は、OneToMany の一方向の関係で FeatureValues と接続されます。
- Product は、ManyToMany の関係で FeatureKind に接続されています。
問題は、ラベルとして FeatureType が必要であり、製品フォームの選択フィールドとしてさまざまな値であることです。製品フォームで機能の種類と関連する値を取得できましたが、それらを選択フィールドに変換する方法がわかりません。
以下は、3 つのエンティティ、コントローラー、フォーム コード、およびコードの結果です。
注:コードを短くするために、余分なものをコードから削除しました。
Product.php
namespace Webmuch\ProductBundle\Entity;
/**
 * @ORM\Table()
 * @ORM\Entity
 */
class Product
{
    /**
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;
    /**
     * @ORM\Column(name="title", type="string", length=255)
     */
    private $title;
    /**
     * @ORM\ManyToMany(targetEntity="FeatureKind", inversedBy="product", cascade={"persist"})
     * @ORM\JoinTable(name="product_featurekind")
     **/
    private $featurekind;
}
FeatureKind.php
namespace Webmuch\ProductBundle\Entity;
/**
 * @ORM\Table(name="feature_kind")
 * @ORM\Entity
 */
class FeatureKind
{
    /**
     * @ORM\Id
     * @ORM\Column(name="id", type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;
    /**
     * @ORM\Column(name="name", type="string", length=50)
     */
    protected $name;
    /**
     * @ORM\ManyToMany(targetEntity="FeatureValue")
     * @ORM\JoinTable(name="feature_kind_value",
     *      joinColumns={@ORM\JoinColumn(name="kind_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="value_id", referencedColumnName="id", unique=true)}
     *      )
     **/
    protected $values;   
}
FeatureValue.php
namespace Webmuch\ProductBundle\Entity;
/**
 * @ORM\Table()
 * @ORM\Entity
 */
class FeatureValue
{
    /**
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;
    /**
     * @ORM\Column(name="value", type="string", length=100)
     */
    protected $value;
}
ProductController.php
public function newAction(Request $request)
{
    $entity = new Product();
    $em = $this->getDoctrine()->getEntityManager();
    $features = $em->getRepository('ProductBundle:FeatureKind')->findAll();
    foreach($features as $feature)
    {
        $featurekind = new FeatureKind();
        $featurekind->setTitle($feature->getTitle());
        foreach($feature->getValue() as $value ){
            $featurekind->getValue()->add($value);
        }
        $entity->getFeaturekind()->add($featurekind);   
    }
    $form = $this->createForm(new ProductType(), $entity);
     if ('POST' === $request->getMethod()) {
        $form->bindRequest($request);
        if ($form->isValid()) {
            $em->persist($entity);
            $em->flush();
            return $this->redirect($this->generateUrl('product_show', array(
                'id' => $entity->getId()
            )));
        }
    }
    return $this->render('ProductBundle:Product:new.html.twig', array(
       'form'   => $form->createView()
    ));
}
ProductType.php
namespace Webmuch\ProductBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
class ProductType extends AbstractType
{
    public function buildForm(FormBuilder $builder, array $options)
    {
        $builder
            ->add('featurekind', 'collection', array('type' => new FeatureKindType()))
            ->getForm();
        }
    public function getDefaultOptions(array $options)
    {
        return array(
            'data_class' => 'Webmuch\ProductBundle\Entity\Product',
            'required' => true
        );
    }
    public function getName()
    {
        return 'product';
    }
}
FeatureKindType.php
namespace Webmuch\ProductBundle\Form;
class FeatureKindType extends AbstractType
{
    public function buildForm(FormBuilder $builder, array $options)
    {
        $builder
            ->add('title')
            ->add('value','collection', array(
                                               'type' => new FeatureValueType(),
                                               'allow_add'=>true))
            ->getForm();
    }
    public function getDefaultOptions(array $options)
    {
        return array(
            'data_class' => 'Webmuch\ProductBundle\Entity\FeatureKind',
        );
    }
    public function getName()
    {
        return 'featurekind';
    }
}

編集:
数日間の作業の後、機能の単純な配列とそれぞれの複数の値に行き詰まりました。
Array
(
    [Color] => Array
        (
            [Red] => Red
            [Green] => Green
        )
    [Size] => Array
        (
            [Large] => Large
            [Medium] => Medium
            [Small] => Small
        )
    [Sleeve Style] => Array
        (
            [Half Sleeved] => Half Sleeved
            [Full Sleeved] => Full Sleeved
            [Cut Sleeves] => Cut Sleeves
        )
)
次のようにフォームを作成しようとしました: $this->choicesには配列が含まれています。
$builder
    ->add('name')
    ->add('slug')
    ->add('active')
;
foreach ($this->choices as $choice) {
    $builder->add('featurekind', 'choice', array(
        'required' => 'false',
        'choices' => $choice,
        'empty_value' => 'Choose an option',
        'empty_data'  => null
    ));
}
$builder->getForm();
上記はプロパティ$featurekindでは機能しません。エラーが発生します:
Notice: Object of class Doctrine\Common\Collections\ArrayCollection could not be converted to int in /vagrant/project/vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/ChoiceList/ChoiceList.php line 457
ただし、フォーム フィールドが関連付けられていないプロパティ ($name など) に関連付けられている場合でも、ループの最後の繰り返しでフォーム フィールドが 1 つだけ作成されます。
私には選択肢がありません。