2016-03-31 7 views
1

Im学習symfony 3 & doctrineと私はエンティティコレクションでフォームを作成しました。エンティティは、ポストとmanyTomanyリレーションを持つタグです。メインフォームは、タグのコレクションを持つPostです。 私のコレクションにタグのID(主キー)のみを渡したいと思います。その結果、私は、タグ形式で一つだけのフィールドがあります。symfonyコレクション内のエンティティ主キー

$builder->add('tagId'); 

私はそれのためにオートコンプリートを作成し、私は主キーのみを必要とする理由thatsの。 フォームを保存した後、doctrineはIDを渡して新しいタグエンティティを作成しますが、新しいものを作成するのではなくそれらのエンティティを探したいと思います。見当もつかない...私はそれが私のコントローラの内部で動作するようにしようとしていた

$formTags = $form->get('tag'); 
foreach ($formTags->getData() as $key => $formTag) 
{ 
    // here i have new entities with id ;/ 
    if($formTag->getTagId()) 
    { 
    // so i tryied to find them, and replace it 
     $formTags->offsetSet($key, 
      array($this->getDoctrine()->getRepository('BlogBundle:Tag') 
          ->find($formTag->getTagId()))); 
    } 
} 

をしかし、symfonyはまた、setDataメソッドで、私に例外をスローします。フォームが提出された後にそれを変更します。私はあなたが私を助けることができることを願っています!

私はデータトランスフォーマーを作ろうとしていました。忘れて言えば:)問題私の変圧器がタグオブジェクトにtagIdフィールドを変更していたか?結果では、私は新しいエンティティでタグオブジェクトを持っていましたが、代わりにタグID値 - 内部に別のオブジェクトがありました。だから私のために期待どおりに動作しません。私はタグIDの代わりにコレクションフィールドのトランスフォーマーを作るべきだと思いますが、どのように動作させるのか分かりません。私はコレクション内の "タグ"フィールドを作成して変換するために試しましたが、doctrineはフィールドに基づいてエンティティから値を取得しようと常に試みましたので、getTag()メソッドは見つかりませんでした。

答えて

1

TagTypeでSymfony DataTransfomerを使用すると、 tagIdをタグエンティティに追加します。 symfonyのDataTransformer docsから

データトランスは(提出背面にあると)形式で表示できる形式にフィールドのデータを変換するために使用されています。

...

は、あなたが(すなわち、各タスクは、それに関連する問題へのオプションの外部キーを持つ)を発行エンティティへのタスクのエンティティから多対1の関係を持っていると言います。すべての可能性のある問題を含むリストボックスを追加すると、最終的には実際には長くなり、読み込みに時間がかかる可能性があります。代わりに、ユーザーが単に発行番号を入力できるテキストボックスを追加することを決定します。

+0

私はこの前にこれを行いました。忘れて言えば:)問題私の変圧器がタグオブジェクトにtagIdフィールドを変更していたか?結果では、tagIdの値を持たない新しいエンティティを持つオブジェクトを保持します。内部に別のオブジェクトがありました。私はタグIDの代わりにコレクションフィールドのトランスフォーマーを作るべきだと思いますが、どのように動作させるのか分かりません。私はコレクション内の "タグ"フィールドを作成して変換するように試しましたが、doctrineはフィールドに基づいてエンティティから値を取得しようと常に試みます。つまり、getTag()メソッドは見つかりませんでした。 – Daimos

+0

最終的には、私はデータトランスフォーマーなしで(本当に悪い方法で)動作させるために近くにあったので有用でしたが、私はあなたのポストの後にそれを使ってますます多くのことを試みていました、そして今働いています – Daimos

1

私は作った。データトランスフォーマーでは、コレクション内のフィールド用ではなく、コレクション用のトランスフォーマーを作成する必要があります。

そのように見えます(作品!)。

マイPostType.phpフォームが(データトランスに関する内部文書のような、)エンティティマネージャを持っている必要があり、およびデータトランス収集のために、私は、コメントを追加しました:

# PostType.php form 
namespace BlogBundle\Form; 

use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilderInterface; 
use Symfony\Component\OptionsResolver\OptionsResolver; 
use Doctrine\ORM\EntityRepository; 
use Symfony\Bridge\Doctrine\Form\Type\EntityType; 
use Symfony\Component\Form\Extension\Core\Type\CollectionType; 
use BlogBundle\Form\DataTransformer\TagToIdTransformer; 
use Doctrine\Common\Persistence\ObjectManager; 
class PostType extends AbstractType 
{ 
private $manager; 

public function __construct(ObjectManager $manager) 
{ 
    // needed for transformer :( 
    // and we need to register service inside app config for this. Details below 
    $this->manager = $manager; 
} 
public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $builder 
     ->add('tag', CollectionType::class, array(
     'entry_type' => TagType::class, 
     'by_reference' => false, 
     'allow_add' => true, 
    )) 
     ->add('save', SubmitType::class, array('label' => 'Save')); 
    $builder->get('tag') 
     ->addModelTransformer(new TagToIdTransformer($this->manager)); 
} 
} 

コンストラクタが例外をトロウます、我々は合格する必要がありますそれに対するObjectManager。これを行うには、バンドル内の設定ファイルを変更してください:

# src/BlogBundle/Resources/config/services.yml 
services: 
    blog.form.type.tag: 
     class: BlogBundle\Form\PostType 
     arguments: ["@doctrine.orm.entity_manager"] 
     tags: 
      - { name: form.type } 

今、コレクション用のトランスを作ってください!私は前に間違っていました。なぜなら、私は内部の文書のように、1つのフィールドのためにしようとしていたからです。コレクションのために、タグの全体配列(manyToManyコレクション)を変換する必要があります:

<?php 
namespace BlogBundle\Form\DataTransformer; 

use BlogBundle\Entity\Tag; 
use Doctrine\Common\Persistence\ObjectManager; 
use Symfony\Component\Form\DataTransformerInterface; 
use Symfony\Component\Form\Exception\TransformationFailedException; 

class TagToIdTransformer implements DataTransformerInterface 
{ 
    private $manager; 

    public function __construct(ObjectManager $manager) 
    { 
     $this->manager = $manager; 
    } 

    /** 
    * Transforms array of objects (Tag) to an array of string (number). 
    * 
    * @param array|null $tags 
    * @return string 
    */ 
    public function transform($tags) 
    { 
     $result = array(); 

     if (null === $tags) { 
      return null; 
     } 
     foreach ($tags as $tag) 
     { 
      $result[] = $tag->getTagId(); 
     } 

     return $result; 
    } 

    /** 
    * Transforms an array of strings (numbers) to an array of objects (Tag). 
    * 
    * @param string $tagsId 
    * @return Tag|null 
    * @throws TransformationFailedException if object (Tag) is not found. 
    */ 
    public function reverseTransform($tagsId) 
    { 
     // no issue number? It's optional, so that's ok 
     if (!$tagsId) { 
      return; 
     } 
     $result = array(); 
     $repository = $this->manager 
      ->getRepository('BlogBundle:Tag'); 
     foreach ($tagsId as $tagId) { 
      $tag = $repository->find($tagId); 
      if (null === $tag) { 
       // causes a validation error 
       // this message is not shown to the user 
       // see the invalid_message option 
       throw new TransformationFailedException(sprintf(
        'An tag with id "%s" does not exist!', 
        $tagId 
       )); 
      } 
      $result[] = $tag; 
     } 
     return $result; 
    } 
} 

すべてがうまくいきます。タグのIDを入力するオートコンプリートでエンティティを簡単に保存することができます

+0

あなたは私の一日を作った! これは私の場合の解決策でした –

関連する問題