简体   繁体   English

具有多对多关系的Symfony实体存储库

[英]Symfony entity repository with many-to-many relationship

I have two entities product and document which are related via a many-to-many relationship with a JOIN table. 我有两个实体productdocument ,它们通过与JOINmany-to-many关系关联。 My product entity looks like below, my document entity currently has no reference back to the product. 我的产品实体如下所示,我的文档实体当前没有对该产品的引用。

/**
 * @ORM\Entity
 * @ORM\Table(name="product")
 * @ORM\Entity(repositoryClass="\MyApp\CmsBundle\Repository\ProductRepository")
 */
class Product
{
    // ...

    /**
     * @ManyToMany(targetEntity="Document")
     * @JoinTable(name="products_documents",
     *      joinColumns={@JoinColumn(name="product_id", referencedColumnName="id")},
     *      inverseJoinColumns={@JoinColumn(name="document_id", referencedColumnName="id")}
     *      )
     **/
     protected $documents;

     // ...

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

    public function addDocument(Document $document)
    {
        $this->documents[] = $document;

        return $this;
    }

    public function removeDocument(Document $document)
    {
        $this->documents->removeElement($document);
    }

    public function getDocuments()
    {
        return $this->documents;
    }

When I present the product on the front-end of the site I also list it's documents. 当我在网站的前端展示产品时,我也会列出它的文档。 However I need to be able to filter them out based on their attributes status and privacy . 但是我需要能够根据它们的属性statusprivacy它们过滤掉。

So I've been trying to create an entity repository to handle this logic but everything I've tried so far has failed. 因此,我一直在尝试创建一个实体存储库来处理这种逻辑,但是到目前为止我尝试过的所有操作都失败了。 What I need to achieve is a query similar to this, but in a Symfony/Doctrine format: 我需要实现的是与此类似的查询,但采用Symfony / Doctrine格式:

SELECT d.*
FROM documents d, products_documents pd,
WHERE pd.product_id = :product_id
  AND pd.document_id = d.id,
  AND d.status = 'PUBLISHED',
  AND d.privacy = 'PUBLIC';

Ideally I would like to be able to do something as simple as this from my controller: 理想情况下,我希望能够从控制器执行以下操作:

// get documents to display on front-end
$documents = $em->getRepository('MyAppCmsBundle:Product')->getDocumentsForProduct($product);

I've got the call to the function working, I'm just not clued up on how to retrieve the data I want. 我已经调用了该函数,但我只是不知道如何检索所需的数据。

UPDATE 更新

This is what I've got so far, whilst maintaining working code, but instead of returning documents it returns all products. 到目前为止,这是我在保持工作代码的同时所获得的,但是它不返回文档而是返回所有产品。 I'm not sure how to add the condition to specify it to the product I pass in, or to return the documents and not the product. 我不确定如何添加条件以将其指定到所传递的产品中,或者返回文档而不是产品。

ProductRepository.php ProductRepository.php

public function getDocumentsForProduct(Product $product, $authenticated = false)
{
    $query = $this->createQueryBuilder('p')
    ->join('MyApp\CmsBundle\Entity\Document', 'd')
    ->where('d.status = :status')
    ->andWhere('d.privacy = :privacy')
    ->setParameters(array(
        'status' => 'PUBLISHED',
        'privacy' => 'PUBLIC',
    ))
    ->getQuery();

    return $query->getResult();
}

If you want it to return documents, you should put it in your DocumentRepository. 如果希望它返回文档,则应将其放在DocumentRepository中。

The 'createQueryBuilder' method autmatically selects entities of the type that belongs to the repository. “ createQueryBuilder”方法自动选择属于存储库的类型的实体。 So in your case, that's Product. 因此,就您而言,这就是产品。 If you put the same code in the DocumentRepository, you should get Document entities. 如果将相同的代码放入DocumentRepository中,则应获取Document实体。

I don't know if there is a way to change this using QueryBuilder. 我不知道是否可以使用QueryBuilder更改此方法。 But you can use DQL instead like this: 但是您可以像这样使用DQL:

$this->getEntityManager()->createQuery('SELECT p FROM YourBundle:Document WHERE ...');

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM