Using EntityRepository::findBy() with Many-To-Many relations will lead to a E_NOTICE in Doctrine

自作多情 提交于 2019-12-02 18:52:43
Lighthart

It is very possible, but the Stock Doctrine Repository does not work this way.

You have two options, depending on your context:

Write a custom method in the Repository.

class PostRepository extends EntityRepository
{
  public function getPosts($id)
  {
    $qb = $this->createQueryBuilder('p');
    $qb->join('p.platform', 'f')
       ->where($qb->expr()->eq('f.id', $id));
    return $qb;
  }
}

Or use the default getter methods in the platform object.

$posts = $platform->getPosts();

You "stripped down to the interesting parts" so it is not obvious if you have this method but it is normally made on

app/console doctrine:generate:entities

Another way, maybe a bit OO/cleaner without using IDs:

public function getPosts(Platform $platform)
{
    $qb = $this->createQueryBuilder("p")
        ->where(':platform MEMBER OF p.platforms')
        ->setParameters(array('platform' => $platform))
    ;
    return $qb->getQuery()->getResult();
}

A better method name would be findPostsByPlatform

This question seems a problem with a ManyToMany relationship which you want BIDIRECTIONAL (and is now UNIDIRECTRIONAL). Use MappedBy to create bidirectionality :

http://doctrine-orm.readthedocs.org/en/latest/reference/association-mapping.html#many-to-many-bidirectional

Practical :

One of your entities is OWNING SIDE, the other INVERSE SIDE. In your example entity named Post is owning side, and entity named Platform is inverse side.

OWNING SIDE setup :

Class Post {
    ...     
    /**
    * @ManyToMany(targetEntity="Platform")
    * @JoinTable(name="map_post_platform",
    *      joinColumns={@JoinColumn(name="post_id", referencedColumnName="id")},
    *      inverseJoinColumns={@JoinColumn(name="platform_id", referencedColumnName="id", unique=true)} )
    **/
    protected $platforms;
    ...
    public function Post() {
        $this->platforms= new ArrayCollection();
    }
    ...
    public function assignToPlatform($platform) {
        $this->platforms[] = $platform;
    } 
    ...
    public function getPlatforms() {
        return $this->platforms;
    }
}

INVERSE SIDE Setup :

Class Platform {
    ...
    /**
    * @ManyToMany(targetEntity="Post", mappedBy="platforms")
    **/
    protected $posts;
    ...
    public function Platform() {
        $this->posts= new ArrayCollection();
    }
    ...
    public function getPosts()
    {
        return $this->posts;
    }
}

EXAMPLE retrieving an array of entities, starting from one of the sides :

$post->getPlatforms();
$platform->getPosts();
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!