8

私は3つのエンティティを持っています:

[Member] ----OneToMany----> [MemberCategory] ---ManyToOne---> [Category]

これは、データベースから結果を取得する限りはうまく機能しますが、フォーム ビルダーで正しいフォーム コントロールを構築することができません。

メンバーが使用するカテゴリのチェックボックスがオンになっているすべてのカテゴリのリストが必要です。最終的には、優先フィールドを追加したいと考えています。

メンバー

class Member
{
    protected $id;

    @ORM\OneToMany(targetEntity="MemberCategory", mappedBy="member")
    protected $categories;
}

カテゴリー

class Category
{
    protected $id;

    @ORM\Column(name="category_name", type="string", length=50, nullable=false, unique=true)
    private $categoryName;
}

会員区分

class MemberCategory
{
    @ORM\Id
    @ORM\ManyToOne(targetEntity="Member")
    @ORM\JoinColumns({
    @ORM\JoinColumn(name="member_id", referencedColumnName="id", onDelete="CASCADE")
    private $member;

    @ORM\Id
    @ORM\ManyToOne(targetEntity="Category")
    @ORM\JoinColumns({
    @ORM\JoinColumn(name="category_id", referencedColumnName="id", onDelete="CASCADE")
    private $category;

    @ORM\Column(name="priority", type="integer", nullable=true)
    protected $priority;
}

機能しないフォームビルダーの明らかな試み。

私が使用する場合:

$builder->add('categories', 'entity', array(
    'class'        => 'SMWMemberBundle:Category',
    'property'     => 'categoryName',
    'multiple'     => true,
    'expanded'     => true,
    'required'     => false
));

すべてのカテゴリを選択できますが、このメンバーの MemberCategory で選択されたものはありません。

私が使用する場合:

$builder->add('categories', 'entity', array(
    'class'        => 'SMWMemberBundle:MemberCategory',
    'property'     => 'category.categoryName',
    'multiple'     => true,
    'expanded'     => true,
    'required'     => false
));

すべてのユーザーの選択されたすべてのカテゴリを取得します。

これを機能させる方法を知っている人はいますか?これはリレーショナル データの明らかな一般的なパターンであり、SQL と PHP を使用すると簡単です。

Symfony 2.3 と Doctrine に簡単な解決策はありますか?

4

3 に答える 3

4

これは私が過去にこの問題を解決した方法です(あなたの例に適用されます)が、これは私が理解したものであるため、あなたのケースには100%適切ではないかもしれません.

まずMemberCategory、ニーズに合ったフォーム タイプを作成します。

<?php    
namespace Company\YourBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class MemberCategoryType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('priority')
            ->add('category', 'entity',
                    array('property' => 'name',
                        'class' => 'CompanyYourBundle:Category'))
        ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Company\YourBundle\Entity\MemberCategory'
        ));
    }

    public function getName()
    {
        return 'company_yourbundle_membercategorytype';
    }
}

Member次に、このフォーム タイプをタイプ フォーム内に追加します。

<?php

namespace Company\YourBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class MemberType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name')
            ->add('members', 'collection', array(
                'type' => new MemberCategoryType(),
                'allow_add' => true,
                'allow_delete' => true,
                'by_reference' => false,));
        ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Company\YourBundle\Entity\Member'
        ));
    }

    public function getName()
    {
        return 'company_yourbundle_membertype';
    }
}

次に、ドキュメントに従って、メンバーに必要な数のカテゴリを追加し、毎回優先順位を割り当てることができます.

于 2013-07-29T16:48:05.797 に答える
1

フォーム内でクエリビルダーを使用する必要があります

$builder->add('categories', 'entity', array(
        'class' => 'SMWMemberBundle:MemberCategory',
        'property'     => 'category.categoryName',
        'query_builder' => function(EntityRepository $er ) use ( ? ) {
           return $er->createQueryBuilder( ? )

          // your query with a left join probably

         }
        'multiple'     => true,
        'expanded'     => true,
        'required' => false
    ));

適切な使用方法については、ドキュメントを参照してください。例については、 symfony2 フォームの querybuilder とパラメーターを参照してください。

于 2013-07-29T16:46:07.840 に答える
0

Cheesemacfly の投稿はそれほど悪くはありませんが、埋め込みフォームと呼ばれ、管理が複雑になる可能性があります。実際、「カスタムリポジトリ」を作成する必要があります http://symfony.com/doc/current/book/doctrine.html#custom-repository-classes

これは、find() や findBy() のような Doctrine2 で ORM オブジェクトを「つかむ」ための新しいメソッドを追加します。

1) バンドルのリポジトリ フォルダに新しいリポジトリを作成します。

<?php
  namespace YourVendor\SMWMemberBundle\Repository;
  use Doctrine\ORM\EntityRepository;

  class CategoryRepository extends EntityRepository{

  public function UsedByMember($member){
  return $this
         ->createQueryBuilder('c')
         ->leftJoin('c.Member', 'mc')
         ->where('mc.member = ?1')
         ->setParameter(1, $member);
}

}

2) Cutom リポジトリをエンティティにアタッチしました

namespace YourVendor\SMWMemberBundle\Entity;
use Doctrine\ORM\Mapping as ORM;

/**
* @ORM\Entity(repositoryClass="YourVendor\SMWMemberBundle\Entity\ProductRepository")
* @ORM\Table(name="Category") 
*/
class Category{

3) Form クラスにコンストラクターを追加し、クエリに必要なエンティティ マネージャーと変数を渡します。

class CategoryUserForm extends AbstractType
{
   private $em;
   private $member ;


   public function __construct(EntityManager $em, $site, $seed)
   {
       $this->em = $em;
       $this->member = $member;

   }

public function buildForm(FormBuilder $builder, array $options)
{
    $qb = $this->em->getRepository('SMWMemberBundle:Category')->UsedByUsers($this->member);
    $builder->add('categories', 'entity', array(
        'class' => 'SMWMemberBundle:MemberCategory',
        'query_builder'     => $qb,
        'multiple'     => true,
        'expanded'     => true,
        'required' => false
    ));
 }

4) コントローラーで、次のようなフォームを作成します。

$editForm = $this->createForm(new CategoryUserForm($em, $member), $category);

お気軽に質問してください。これがあなたが探しているものであることを願っています;)

于 2013-07-29T17:35:13.000 に答える