0

多対多の関係に問題があります。querybuilder クエリの参照テーブルにアクセスしたいと考えています。多対多の関係では参照テーブルにアクセスできないため、2 つの一対多の関係を設定しました。私の構造は次のようになります:

User ---> UserUserCategory <--- UserCategory

上記の構造には 2 つの 1 対多の関係があり、データベースで正常に動作しています。データベース (UserUserCategory) に次のデータを持つユーザーがいる場合:

Table User
ID | Name
1  | Bart
2  | Gerard

Table Category 
ID | Name
1  | Officer
2  | Medic

Table UserUserCategory
User | Category
1    | 1
2    | 2

バートはオフィサーで、ジェラルドはメディックです。しかし、データを取得しようとすると、Bart がメディックで、Gerard のカテゴリの値が「null」であると表示されました。

私のユーザーエンティティ:

/**
 * Entity Class representing a post of our User module.
 * 
 * @ORM\Entity
 * @ORM\Table(name="user")
 * @ORM\Entity(repositoryClass="User\Repository\UserRepository")
 * 
 */
class User extends zfcUser implements UserInterface
{
    /**
     * Categories from user
     * 
     * @ORM\OneToMany(targetEntity="User\Entity\UserUserCategory", mappedBy="user_id", cascade={"remove", "persist"})
     * @var UserUserCategory
     * @access protected
     */
    protected $user_usercategories;

//name & user_id comes here

    /**
     * Constructor to make a new ArrayCollection for addresses
     * 
     * 
     */
    public function __construct()
    {        
        $this->user_usercategories = new ArrayCollection();
    }

      /**
     * @param Collection $categories
     */    
    public function addUserUserCategories(Collection $user_usercategories)
    {
        foreach ($user_usercategories as $user_usercategorie) {
            $user_usercategorie->setUser($this);
            $this->user_usercategories->add($user_usercategorie);
        }
    }

   /**
     * @param Collection $categories
     */
    public function removeUserUserCategories(Collection $user_usercategories)
    {
        foreach ($user_usercategories as $user_usercategorie) {
            $user_usercategorie->setUser(null);
            $this->user_usercategories->removeElement($user_usercategorie);
        }
    }

    /**
     * @return Collection
     */
     public function getUserUserCategories()
     {
         return $this->categories;
     }
}

私の UserCategory エンティティ:

/**
 * A User category entity.
 * @ORM\Entity
 * @ORM\Table(uniqueConstraints={@ORM\UniqueConstraint(name="unique_name_parentId", columns={"name", "parent_id"})})
 * @ORM\HasLifecycleCallbacks
 */
class UserCategory extends Category
{    
    /**
     * User_usercategories
     * 
     * @ORM\OneToMany(targetEntity="User\Entity\UserUserCategory", mappedBy="category_id")
     * @var UserUserCategory
     * @access protected
     */
    protected $user_usercategories;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->user_usercategories = new ArrayCollection();
    }

    /**
     * @param Collection $categories
     */    
    public function addUserUserCategories(Collection $user_usercategories)
    {
        foreach ($user_usercategories as $user_usercategorie) {
            $user_usercategorie->setCategory($this);
            $this->user_usercategories->add($user_usercategorie);
        }
    }

   /**
     * @param Collection $categories
     */
    public function removeUserUserCategories(Collection $user_usercategories)
    {
        foreach ($user_usercategories as $user_usercategorie) {
            $user_usercategorie->setCategory(null);
            $this->user_usercategories->removeElement($user_usercategorie);
        }
    }

    /**
     * @return Collection
     */
     public function getUserUserCategories()
     {
         return $this->categories;
     }
}

私の UserUserCategory エンティティ:

/**
 * Entity Class representing a post of our User_UserCategory entity.
 * 
 * @ORM\Entity
 * @ORM\Table(name="user_usercategory")
 * 
 */
class UserUserCategory
{
    /**
     * User with a category
     * 
     * @ORM\ManyToOne(targetEntity="User\Entity\User", inversedBy="user_usercategories")
     * @ORM\JoinColumn(name="user_id", referencedColumnName="user_id", nullable=false, onDelete="CASCADE")
     * @ORM\Id
     * 
     * @var User
     * @access protected
     */
    protected $user_id;

    /**
     * Category from user
     * 
     * @ORM\ManyToOne(targetEntity="User\Entity\UserCategory", inversedBy="user_usercategories")
     * @ORM\JoinColumn(name="category_id", referencedColumnName="id", nullable=false, onDelete="CASCADE")
     * @ORM\Id
     * 
     * @var Category
     * @access protected
     */
    protected $category_id;

        public function getUser()
    {
        return $this->user;
    }

    /**
     * Set User
     * 
     * @param User $user
     * @return User
     */
    public function setUser(User $user = null)
    {
        //die('setUser');
        $this->user = $user;
        return $this;
    }

    public function getCategory()
    {
        return $this->category;
    }

    /**
     * Set Category
     * 
     * @param Category $category
     * @return Category
     */
    public function setCategory(Category $category = null)
    {
        $this->category = $category;
        return $this;
    }
}

次の行を実行すると、間違った結果が返されます。間違ったカテゴリが表示されます:

\Doctrine\Common\Util\Debug::dump($this->getEntityManager()->find('User\Entity\User', '49')->user_usercategories); 死ぬ;

結果:

array(1) {
  [0]=>
  object(stdClass)#452 (3) {
    ["__CLASS__"]=>
    string(28) "User\Entity\UserUserCategory"
    ["user_id"]=>
    string(16) "User\Entity\User"
    ["category_id"]=>
    string(24) "User\Entity\UserCategory"
  }
}

category_id にはメディックが印刷されています。オフィサーが戻ってくることを期待しています。

私の他のユーザー (id=60) では、category_id フィールドは「null」です。そのため、Doctrine は UserUserCategory の最初の入力をスキップし、2 番目から開始して、最後のカテゴリを取得できなくなっているようです。

4

1 に答える 1

1

問題はありませんが、あなたのコードは非常に読みにくいと思います。いくつかの修正を行うことをお勧めします。それが問題の解決に役立つ場合もあります。

1: 名前付け: UserCategory の代わりに、Category に名前を変更します。カテゴリに異なるタイプがある場合は、次のような定数の値を使用して新しい列「タイプ」を作成します

 class Category
 {
    const TYPE_USER = 1 ;
    ....

2: addCategories(Collection $array) の代わりに、次のような単数バージョンを実行します

public function addCategory(Category $category)
{
    $reference = new UserCategory() ;
    $reference->setUser($this) ;
    $reference->setCategory($category) ;
    $this->user_categories->add($reference) ;
}

public function removeCategory(Category $category)
{
    foreach($this->user_categories as $reference) {
        if ( $reference->getCategory() === $category ) 
            $this->user_categories->removeElement($reference) ;
    }
}

Symfony2 はこのようなメソッドを自動的に認識します。リレーションが複数形 (カテゴリなど) であっても、s2 は単数形の addCategory メソッドと removeCategory メソッドを見つけます。

カテゴリの配列を取得するには、次を使用します。

public function getCategories()
{
    $categories = new ArrayCollection() ;
    foreach($this->user_categories as $reference) {
        $categories->add( $reference->getCategory() ) ;
    }
    return $categories ;
}

このようにすれば、おそらくあなたが抱えている問題は解決するでしょう。

于 2013-05-14T13:54:58.007 に答える