0

私は Zend Framework 2 と Doctrine 2 にかなり慣れていないので、問題を検索またはデバッグする方法さえわかりません。

私は3つのデータベーステーブルを持っています

1. 広告
ID
adverttitle ...

2. カテゴリ
ID
カテゴリ名 ...

3. advert_category
advert_id
カテゴリ_id

広告とカテゴリの 2 つのエンティティを作成しました。これで、選択するカテゴリを表示するフォームができました。jQuery を使用して、カテゴリをドロップダウンではなくリストとして表示し、選択可能な関数も一緒に表示します。したがって、カテゴリをクリックすると、このリスト要素の値がカテゴリと呼ばれる非表示の入力フィールドに入力されます。

フォームを表示すると、非表示のカテゴリ入力フィールドが空の代わりにDoctrine\Common\Collections\ArrayCollection@000000000.....の値を取得したことを除けば、すべて正常に動作します。ここで何が間違っていますか?解決策を見つけようとしましたが、うまくいきませんでした。

最終的に複数のカテゴリを保存できるようにするため、ManyToMany 関係を選択しました。現在は 1 のみで動作していますが、この方法で後で変更できるはずです。

ここで私の広告エンティティ:

namespace Advert\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use DateTime;

/** Advert
 * 
 * @ORM\Table(name="advert")
 * @ORM\Entity(repositoryClass="Advert\Repository\AdvertRepository")
 */

class Advert
{
 /**
  * @var integer
  *
  * @ORM\Column(name="id", type="integer", nullable=false)
  * @ORM\Id
  * @ORM\GeneratedValue(strategy="IDENTITY")
  */
  private $id;


 /**
  * @var string
  *
  * @ORM\Column(name="advert_title", type="string", length=255, nullable=true)
  */
  private $advertTitle; 

 /** 
  * @ORM\ManyToMany(targetEntity="Category", inversedBy="adverts", cascade={"persist"}) 
  * @ORM\JoinTable(name="advert2category") 
  */
  private $categories;

  public function __construct() 
  { 
    $this->categories = new ArrayCollection();
  }

 /**
  * Set categories
  *
  * @param ArrayCollection $category
  * @return Advert
  */
  public function setCategories($categories)
  {
    $this->categories = $categories;
    return $this;
  }


 /**
  * Get categories
  *
  * @return ArrayCollection
  */
  public function getCategories()
  {
    return $this->categories;
  }

  /**
   * @param Collection $categories
   */
  public function addCategories($categories)
  {
    foreach ($categories as $category) {
        $this->categories->add($category);
    }
  }

  /**
   * @param Collection $categories
   */
  public function removeCategories($categories)
  {
    foreach($categories as $category){
        $this->categories->removeElement($category);
    }

  }

これを引き起こす広告エンティティにエラーはありますか? 誰かが助けてくれることを願っています。数週間前からこの問題があり、正しく動作させることができません。

更新 - フォームを呼び出すために、コントローラーにフォームとパーツを追加しました

以下のフォームには、2 つのドロップダウン要素と 2 つの非表示の入力フィールドが表示されます。2 つのドロップダウン フィールドは、jQuery を介して選択可能なリストに変換されます。Maincategory からリスト要素をクリックすると、選択した Maincategory の Subcategories が選択可能なリストとして再び表示されます。MaincategoryID は非表示の categoryID フィールドに入力されます。リストからサブカテゴリを選択するとすぐに、そのカテゴリの ID が非表示のカテゴリ フィールドに書き込まれます。「次へ」ボタンをクリックすると、$_POST['categories'] の値が advertID とともにリンク テーブルに保存されます。

use Zend\Form\Form;
use DoctrineModule\Persistence\ObjectManagerAwareInterface;
use Doctrine\Common\Persistence\ObjectManager;

class CategoryForm extends Form implements ObjectManagerAwareInterface
{

protected $objectManager;


public function __construct()
{       
    $this->setInputFilter(new AdvertFilter());
    parent::__construct('category');


}

public function init()
{
    $this->setAttribute('method', 'post');




    $this->add(array(
            'name' => 'categories',
            'attributes' => array(
                    'type' => 'hidden',
                    'id'    => 'categories',

            ),
            'options'=> array(
                    'label'=> 'categories',
                    ),


    ));


    $this->add(
            array(

                    'type' => 'DoctrineModule\Form\Element\ObjectSelect',
                    'name' => 'categoriesList',

                    'options' => array(

                            'object_manager' => $this->getObjectManager(),
                            'label' => 'Main Category',
                            'target_class'   => 'Advert\Entity\Category',
                            'property'       => 'name',
                            'is_method' => true,

                            'find_method'        => array(
                                    'name'   => 'getMainCategories',
                            ),
                    ),
                    'allow_empty'  => true,
                    'required'     => false,
                    'attributes' => array(
                            'id' => 'categoryList',
                            'multiple' => true,


                    )
            )
    );

    $this->add(
            array(
                    'type' => 'DoctrineModule\Form\Element\ObjectSelect',
                    'name' => 'subcategoryList',
                    'options' => array(
                            'object_manager' => $this->getObjectManager(),
                            'label' => 'Sub Category',


                            'target_class'   => 'Advert\Entity\Category',
                            'property'       => 'name',

                            'is_method' => true,
                            'find_method'        => array(
                                    'name'   => 'getSubCategories',
                            ),
                    ),
                    'allow_empty'  => true,
                    'required'     => false,
                    'attributes' => array(

                            'id' => 'subcategoryList',
                            'multiple' => true,
                            )
            )
    );


    $this->add(array(
            'type' => 'hidden',
            'name' => 'categoryID',
            'options'=> array(
                    'label'=> 'categoryID'),
            'attributes' => array(
                    'id' => 'categoryID',
                    'value' => '1',
            )
    ));

   $this->add(array(
            'name' => 'submit',
            'attributes' => array(
                    'type'  => 'submit',
                    'value' => 'Next',
                    'id' => 'submitbutton',
            ),
    ));



}

public function setObjectManager(ObjectManager $objectManager)
{
    $this->objectManager = $objectManager;
}

public function getObjectManager()
{
    return $this->objectManager;
}

}

私のコントローラーでは、次の方法でフォームを呼び出します。

    $sl = $this->getServiceLocator();
    $form = $sl->get('FormElementManager')->get('\Advert\Form\CreateForm');

    # create a new, empty entity
    $advert = new Advert();

    # set the hydrator to connect form and entity
    $form->setHydrator(new DoctrineHydrator($this->getEntityManager(),'Advert\Entity\Advert'));

    # connect form and entity
    $form->bind($advert);
4

1 に答える 1

0

まず、双方向のリレーションシップは結合テーブルを使用しません。マッピングは双方向のように見えますが、3 番目のテーブルを使用しようとしています: advert_category.

$categoriesエンティティのプロパティのマッピングをAdvert一方向の関係に変更することをお勧めします。

class Advert
{
     // ...

    /**
     * @ORM\ManyToMany(targetEntity="Category")
     * @ORM\JoinTable(name="advert_category",
     *      joinColumns={@ORM\JoinColumn(name="advert_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="category_id", referencedColumnName="id")}
     *      )
     **/
    protected $categories;

    // ...
}

また、 DoctrineObject hydratorを利用したい場合は、エンティティ内にaddCategories(Collection $categories)andremoveCategories(Collection $categories)メソッドを実装する必要があります。( DoctrineORMModuleを使用していると仮定しています)。Advert

この時点で、あなたのCategoryエンティティは何も知らないはずでありAdvert、 のようなエンティティ メソッドを介してカテゴリ インスタンスからすべての広告に直接アクセスすることはできません$category->getAdverts()。ただし、必要に応じて、 getAdvertsByCategoryId($categoryId)AdvertRepository にメソッドを簡単に記述できます。

最後の詳細は、CategoryFieldset(エンティティをオブジェクトとして使用する必要もあります)が必要であり、構成キーを使用するか、インスタンス自体を直接提供Categoryして、フォームのcategories要素でこのフィールドセットを指す必要があります。target_element

例えば:

$formManager = $serviceLocator->get('FormElementManager');
$form = $formManager->get('your\form\name');
$form->add(
    array(
        'name' => 'categories',
        'type' => 'Zend\Form\Element\Collection',
        'options' => array(
            'target_element' => $formManager->get('your\fieldset\name');
            // or you can do this but probably you will also need $entityManager
            // inside the CategoryFieldset
            // 'target_element' => new CategoryFieldset();
            ),
        )
    );

FormElementManagerとで直接インスタンス化する代わりに、 を使用してフォームとフィールドセットのインスタンスを取得することnew AdvertForm()を強くお勧めしますnew CategoryFieldset()。また、フィールドセットとフォームに同様の依存関係を正しい方法でAbstractFormElementFactory注入することをお勧めします。$entityManager

それが役に立てば幸い。

于 2014-11-29T10:45:15.143 に答える