これは古い質問ですが、とにかく答えると思いました。ObjectSelect
前の回答では、Doctrine を使用していません。
OneToOne の関係を持ち、「One-table」にレコードを追加したくないと言います。ここでは、単方向の OneToOne関係があると想定しています。
ただし、エンティティとして「製品」と「ブランド」を取得した場合は、OneToMany 双方向の関係がより適している可能性があります;)
ただし、OneToOne を使用すると、エンティティは次のようになります。
class Brand {
/**
* @var int
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* @var string
* @ORM\Column(name="name", type="string", nullable=false, length=128)
*/
protected $name;
//Getters/Setters
}
class Product {
/**
* @var int
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* @var string
* @ORM\Column(name="name", type="string", nullable=false, length=128)
*/
protected $name;
//Change below "OneToOne" to "ManyToOne" for proper product + brand relationship. Just this change will leave it as uni-directional.
/**
* @var Brand
* @ORM\OneToOne(targetEntity="Brand", fetch="EAGER")
* @ORM\JoinColumn(name="brand", referencedColumnName="id")
*/
protected $brand;
//Getters/Setters
}
エンティティが正しいと仮定すると、ObjectSelect
Doctrine へのビルドを使用する必要があります。
class ProductForm
{
/** @var ObjectManager */
protected $objectManager;
public function __construct($name = 'product-form', $options = [])
{
parent::__construct($name, $options);
}
public function init()
{
$this->add([
'type' => 'DoctrineModule\\Form\\Element\\ObjectSelect',
'name' => 'brand',
'required' => true,
'attributes' => [
'id' => 'selectBrand',
'multiple' => false,
'value' => null,
],
'options' => [
'label' => 'Select brand',
'object_manager' => $this->getObjectManager(),
'target_class' => Brand::class,
'property' => 'id',
'is_method' => true,
'find_method' => [
'name' => 'findBy',
'params' => [
'criteria' => [],
'orderBy' => ['name' => 'ASC'],
],
],
'empty_option' => '--- Select Brand ---',
'label_generator' => function (Brand $entity) {
return $entity->getName();
}
],
]);
}
/**
* @return ObjectManager
*/
public function getObjectManager()
{
return $this->objectManager;
}
/**
* @param ObjectManager $objectManager
*/
public function setObjectManager(ObjectManager $objectManager)
{
$this->objectManager = $objectManager;
}
}
Module.php
このフォームをロードできるようにを設定してください。getServiceConfig()
それに関数を追加します。
public function getServiceConfig()
{
/** @var ServiceManager $sm */
return [
'factories' => [
'product_form' => function ($sm)
{
$form = new ProductForm();
$form->setInputFilter(new ProductInputFilter());
/** @var EntityManager $entityManager */
$entityManager = $sm->get('doctrine.entitymanager.orm_default');
//Set Doctrine ObjectManager
$form->setObjectManager($entityManager);
//Set Doctrine Object as Hydrator
$form->setHydrator(new DoctrineObject($entityManager, Product::class));
//Set Doctrine Entity
$form->setObject(new Product());
//Initialize elements onto form
$form->init();
return $form;
},
],
];
}
}
次に、コントローラーにフォームをロードします。
$form = $this->getServiceLocator()->get('product_form');
===========================
注: これは Zend Framework 2.5.2 まで機能します。