よし、ようやくサービスとしての作り方がわかった気がする。「なぜそれをサービスにするのですか?」と聞かれるかもしれません。これは、エンティティ マネージャーを挿入する必要があるためです。次のチュートリアルがお役に立てば幸いです。
カスタム フォーム タイプの Preferred_choices
データベースにいくつかの国が保存されていて、それらがCountry
エンティティであり、Doctrine で適切に定義されているとします。しかし、問題があります。世界中には 250 近くの国があり、ユーザーは 1 つの国の出身である可能性が最も高いのです。たとえば、国をデフォルトで選択するか、リストの一番上に置く必要があるとします。
ステップ 1: フィールドに入力する
カスタム フォーム タイプを作成しているとしますCountryType
。定義しましょう。
class CountryType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('country', 'entity', array(
'class' => 'Acme\AcmeBundle\Locality\Country',
'property' => 'name',
'query_builder' => function (EntityRepository $repository) {
$qb = $repository->createQueryBuilder('country')->orderBy('country.name');
return $qb;
}
));
}
public function getDefaultOptions(array $options)
{
return array('data_class' => 'Acme\AcmeBundle\Locality\Country');
}
public function getName()
{
return 'countrytype';
}
}
そして、どこかから呼び出すと、
$builder->add('country', new CountryType());
デフォルトで選択された国を取得しないことを除いて、すべてうまく機能します。さらに悪いことに、追加しようとすると
'preferred_choices' => array(15) //Say, 15 is the id of the country
あなたのオプションに、例外が発生します。そして、いくつかの奇妙な理由で、これを行う:
$defaultCountry = new Country();
$defaultCountry->setId(15);
その後
'preferred_choices' => array($defaultCountry)
どちらも機能しません。
ここから楽しみが始まります。
ステップ 2: EntityManager を追加する
必要なエンティティを検索するには、データベースにクエリを実行する必要があります。そして今は Doctrine がないのでアクセスできませんEntityManager
。クラスに 1 つ追加し、コンストラクターに引数として渡し、クラスのプライベート プロパティとして格納します。
class CountryType extends AbstractType
{
//Add this
public function __construct(EntityManager $em)
{
$this->em = $em;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('country', 'entity', array(
'class' => 'Acme\AcmeBundle\Locality\Country',
'property' => 'name',
'query_builder' => function (EntityRepository $repository) {
$qb = $repository->createQueryBuilder('country')->orderBy('country.name');
return $qb;
}
));
}
public function getDefaultOptions(array $options)
{
return array('data_class' => 'Acme\AcmeBundle\Locality\Country');
}
public function getName()
{
return 'countrytype';
}
//Add this
private $em;
}
その後、データベースにクエリを実行します。
class CountryType extends AbstractType
{
public function __construct(EntityManager $em)
{
$this->em = $em;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
//Add the following lines
$qb = $this->em->createQueryBuilder();
$resultset = $qb->select('country')
->from('Acme\AcmeBundle\Locality\Country', 'country')
->where('country.id = ?1')
->setParameter(1, 15)
->getQuery()
->execute();
$default = $resultset[0];
$builder->add('country', 'entity', array(
'class' => 'Acme\AcmeBundle\Locality\Country',
'property' => 'name',
'preferred_choices' => array($default), //Add this too
'query_builder' => function (EntityRepository $repository) {
$qb = $repository->createQueryBuilder('country')->orderBy('country.name');
return $qb;
}
));
}
public function getDefaultOptions(array $options)
{
return array('data_class' => 'Acme\AcmeBundle\Locality\Country');
}
public function getName()
{
return 'countrytype';
}
private $em;
}
しかし、ここで問題が発生しました。もう呼び出すことはできません!! EntityManager
特にこれをコントローラーから呼び出すのではなく、埋め込む場合はどうすればよいでしょうか? ここで魔法がかけられます。
ステップ 3: サービスにする
なんで?このようにして an を注入できるEntityManager
からです。次の行に移動しAcme/AcmeBundle/Resources/cofig/services.yml
て追加します。
acme.acmebundle.countrytype:
class: Acme\AcmeBundle\Types\CountryType
arguments: ["@doctrine.orm.entity_manager"]
tags:
- { name: form.type, alias: countrytype }
ここにいくつかのメモ:
- サービスに渡される引数は別のサービス、つまり Doctrine
EntityManager
です。この引数は関数のコンストラクターに渡され、別の場所から注入されます。このようにして、常にEntityManager
.
- タグには、指定された両方のタグが含まれていることを確認してください。
alias
タグは、getName()
カスタム タイプ (この場合はcountrytype
.
依存性注入とサービスについて詳しく知りたい場合は、ここにアクセスしてください:サービス コンテナー。
さて、大きな問題です。それをどのように呼ぶのでしょうか?
ステップ 4: サービスを呼び出す
やり方は非常に簡単です。この行を覚えていますか?
$builder->add('country', new CountryType());
ここで、次のように変更します。
$builder->add('country', 'countrytype');
それでおしまい!これで、カスタム タイプにエンティティ マネージャーがアタッチされ、引数を渡す必要がなくなりました。次のプロジェクトで頑張ってください!