Dla projektu Symfony2 musiałem stworzyć relację między postem na blogu a tzw. Platformami. Platforma definiuje określony filtr na podstawie domeny używanej do przeglądania witryny. Na przykład: jeśli dołączysz do witryny przez adres url first-example.com, witryna będzie udostępniać tylko posty na blogu, które są połączone z tą konkretną platformą.Używanie EntityRepository :: findBy() z wieloma relacjami prowadzi do E_NOTICE w Doctrine
W tym celu utworzyłem dwie jednostki: Post i Platform. Potem zmapowałem ich razem z relacją wiele do wielu. Próbuję pobrać dane za pośrednictwem relacji Wiele do wielu z wbudowanej funkcji findBy()
w Doctrines '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
Gdzie jest poprawne repozytorium dla podmiotu Post
i $platform
istniejący Platform
obiektu.
Tak czy inaczej: skończę otrzymuję następujący błąd:
ErrorException: Notice: Undefined index: joinColumns in [...]/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php line 1495
[...]/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php:1495
[...]/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php:1452
[...]/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php:1525
[...]/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php:1018
[...]/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php:842
[...]/vendor/doctrine/orm/lib/Doctrine/ORM/EntityRepository.php:157
[...]/src/Foobar/BlogBundle/Tests/ORM/PostTest.php:102
Czy to w ogóle możliwe, aby odzyskać związanych z udziałów w jednostkach w wiele do wielu relacji ten sposób, czy jestem zmuszony pisać te funkcje przez siebie? Dziwne jest to, że: Doctrine nie rzuci żadnego błędu w stylu: "To niemożliwe", ale wewnętrznego: E_NOTICE
. To dlatego myślę, że to powinno być możliwe, ale brakuje mi tutaj pewnych punktów.
Pozbawieni interesujących części, dwie Jednostki wyglądają tak.
<?php
namespace Foobar\CommunityBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
// [...] other namespace stuff
/**
* @ORM\Entity(repositoryClass="Foobar\CommunityBundle\Entity\Repository\PlatformRepository")
* @ORM\Table(name="platforms")
*/
class Platform
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
// [...] other field stuff
}
<?php
namespace Foobar\BlogBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
// [...] other namespace stuff
/**
* @ORM\Entity(repositoryClass="Foobar\BlogBundle\Entity\Repository\PostRepository")
* @ORM\Table(name="posts")
*/
class Post implements Likeable, Commentable, Taggable, PlatformAware
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\ManyToMany(targetEntity="Foobar\CommunityBundle\Entity\Platform", cascade={"persist"})
* @ORM\JoinTable(name="map_post_platform",
* joinColumns={@ORM\JoinColumn(name="post_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="platform_id", referencedColumnName="id")}
* )
*/
protected $platforms;
// [...] other fields
/**
* Constructor
*/
public function __construct()
{
// [...]
$this->platforms = new ArrayCollection();
}
}
I oczywiście plików composer.json (jak również okrojona do odpowiednich linii)
{
[...]
"require": {
"php": ">=5.3.3",
"symfony/symfony": "2.1.*",
"doctrine/orm": ">=2.2.3,<2.4-dev",
"doctrine/doctrine-bundle": "1.0.*",
"doctrine/doctrine-fixtures-bundle": "dev-master",
[...]
},
[...]
}
Dziękuję za odpowiedź. Tylko mały dodatek. Twoja pierwsza metoda polega na pisaniu własnej funkcji w niestandardowym repozytorium. Być może wyraziłem się niejasno, ale próbowałem pobrać powiązane obiekty za pomocą wbudowanej funkcji 'find *()' Doctrine. Druga metoda nie działa, ponieważ mam jednokierunkowe powiązanie. W związku z tym nie ma właściwości '$ posts' na' Platformie', a co za tym idzie, żadnych programów pobierających i ustawiających. Niemniej twoja odpowiedź bardzo mi pomaga, ponieważ teraz jestem bardziej pewny, że nie można po prostu użyć wbudowanych sposobów, aby uzyskać filtrowane powiązania wielu do wielu. – devsheeep