Использование EntityRepository:: findBy() с отношениями "многие ко многим" приведет к E-уведомлению в доктрине
для проекта Symfony2 мне пришлось создать связь между сообщением в блоге и так называемыми платформами. Платформа определяет определенный фильтр на основе домена, используемого для просмотра сайта. Например: если вы присоединитесь к сайту по url-адресу first-example.com, сайт будет предоставлять только сообщения в блогах, которые подключены к этой конкретной платформе.
для этого я создал два объекта Post и Platform. Впоследствии я сопоставил их вместе с отношениями "многие ко многим".
Я пытаюсь извлеките данные через это отношение "многие ко многим" из встроенной функции findBy()
в доктринах' EntityRepository
.
// every one of these methods will throw the same error
$posts = $postRepo->findBy(array('platforms' => array($platform)));
$posts = $postRepo->findByPlatforms($platform);
$posts = $postRepo->findByPlatforms(array($platform));
здесь $postRepo
правильный репозиторий для Post
сущность и $platform
существующей
3 ответов
Это очень возможно, но хранилище доктрины запаса не работает таким образом.
у вас есть два варианта, в зависимости от вашего контекста:
написать пользовательский метод в репозитории.
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;
}
}
или используйте методы геттера по умолчанию в объекте платформы.
$posts = $platform->getPosts();
вы "раздели до интересных частей", так что это не очевидно, если у вас есть этот метод, но он обычно сделан на
app/console doctrine:generate:entities
другой способ, возможно, немного OO / cleaner без использования идентификаторов:
public function getPosts(Platform $platform)
{
$qb = $this->createQueryBuilder("p")
->where(':platform MEMBER OF p.platforms')
->setParameters(array('platform' => $platform))
;
return $qb->getQuery()->getResult();
}
лучшим именем метода было бы findPostsByPlatform
этот вопрос кажется проблемой с отношениями ManyToMany, которые вы хотите двунаправленными (и теперь однонаправленными). Используйте MappedBy для создания двунаправленности:
практика :
одна из ваших сущностей владеет стороной, другая обратная сторона. В вашем примере сущность с именем Post является владельцем side, а сущность с именем Platform обратная сторона.
иметь бортовую установку:
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;
}
}
настройка обратной стороны:
Class Platform {
...
/**
* @ManyToMany(targetEntity="Post", mappedBy="platforms")
**/
protected $posts;
...
public function Platform() {
$this->posts= new ArrayCollection();
}
...
public function getPosts()
{
return $this->posts;
}
}
пример извлечения массива сущностей, начиная с одной из сторон :
$post->getPlatforms();
$platform->getPosts();