1

これはおそらくこの質問と同様の問題だと思いますが、まだコメントすることはできず、回答のない回答を提供してそれをぶつけたくありませんでした。

コメントをさまざまなエンティティ タイプに直接関連付けることができるコメント付き Symfony2 バンドルを作成しているので、抽象的なコメント 'スレッド' エンティティを作成しました。これは、コメントを受け取ることができるオブジェクト タイプごとの具体的なスレッド エンティティによって拡張されます。 .

たとえば、Story エンティティにコメントできるようにする必要があるため、Thread を拡張し、Story にリンクする OneToOne 属性を指定する具体的な StoryThread エンティティを作成しました。アイデアは、私ができるということです$storyThread->findOneBy('story', $story)->getComments();。ただし、findOneBy は常に null を返します。デバッグから取得した未加工の SQL を実行し、関連する story_id を入力すると、期待どおりの結果が得られます。

抽象スレッド エンティティは次のとおりです。

use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * @ORM\Entity(repositoryClass="Joe\Bundle\CommentBundle\Repository\ThreadRepository")
 * @ORM\Table(name="comment_threads")
 * @ORM\MappedSuperClass
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="thread_type", type="string")
 * @ORM\DiscriminatorMap( {"story" = "Joe\Bundle\StoryBundle\Entity\StoryThread"} )
 */
abstract class Thread
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\Column(type="boolean")
     */
    protected $enabled = true;

    /**
     * @var datetime $createdAt
     *
     * @Gedmo\Timestampable(on="create")
     * @ORM\Column(name="created_at", type="datetime")
     */
    protected $createdAt;

    /**
     * @ORM\OneToMany(targetEntity="Comment", mappedBy="thread_id", cascade={"persist"})
     * @param ArrayCollection $data
     */
    protected $comments;


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

具体的な StoryThread エンティティは次のとおりです。

use Doctrine\ORM\Mapping as ORM;
use Joe\Bundle\CommentBundle\Entity\Thread as AbstractThread;

/**
 * @ORM\Entity(repositoryClass="Joe\Bundle\StoryBundle\Repository\StoryThreadRepository")
 * @ORM\Table(name="story_comment_threads")
 */
class StoryThread extends AbstractThread
{
    /**
     * @ORM\OneToOne(targetEntity="Story")
     * @ORM\JoinColumn(name="story_id", referencedColumnName="id")
     */
    protected $story;

    /**
     * @var datetime $createdAt
     */
    protected $createdAt;


    public function __construct()
    {
        $this->comments = new \Doctrine\Common\Collections\ArrayCollection();
    }

最後に、特定の Story エンティティから StoryThread オブジェクトを取得しようとしている方法を次に示します (getThreadEntityName は完全修飾 StoryThread クラス名を取得し、getObjectColumn は ObjectThread エンティティをそのオブジェクトにマップするために使用される列の名前を返します。この場合「物語」)

/**
 * @param CommentableInterface $object
 * @return AbstractThread
 */
public function findThreadByObject(CommentableInterface $object)
{
    /** @var $repository ThreadRepository */
    $repository = $this->em->getRepository($object->getThreadEntityName());

    $thread = $repository->findOneBy(array(
        $repository->getObjectColumn() => $object
    ));

    if (!$thread) {
        $thread = $this->createThread($object);
    }

    return $thread;
}

findOneBy メソッド内で生成される SQL は次のとおりです (? を 1 などの実際のストーリー ID に置き換えると、期待どおりに 1 つの結果が返されます)。

SELECT t1.id AS id2, t1.enabled AS enabled3, t1.created_at AS created_at4, t0.story_id AS story_id5, t1.thread_type FROM story_comment_threads t0 INNER JOIN comment_threads t1 ON t0.id = t1.id WHERE t0.story_id = ?

findOneBy メソッドを機能させる方法、またはおそらく別の方法で機能させる方法を誰か教えてもらえますか? ありがとう

4

1 に答える 1

1

「ストーリー」列がストーリーエンティティを参照しているため、オブジェクトを提供する必要があると思っていましたが、代わりに id を使用する必要があったことがわかりました。

$thread = $repository->findOneBy(array(
    $repository->getObjectColumn() => $object->getId()
));
于 2012-05-15T14:19:39.780 に答える