Od niedawna bawię się Symfony2, do tej pory jakoś nie po drodze mi było z SF i pracowałem z innymi frameworkami (Zend, Yii).
Mam problem z odwzorowaniem relacji 1-1 w encjach Doctrine.
Mam 2 encje User i Profile.
Każdy użytkownik może, ale nie musi mieć profilu.
W tabeli Profile jako klucz główny i jednocześnie klucz obcy User zastosowałem pole 'uidx' (nie wydało mi się sensowne tworzenie osobnego klucza głównego AI w tabeli Profile, skoro i tak 1 User może mieć 1 Profile, gdzie id_usera=id_profilu).
Teraz w czym problem.
Główną tablicą w mojej bazie jest User. Chciałem to zrobić tak, że najpierw tworzę użytkownika, później mogę utworzyć mu profil na zasadzie:
- pobierz istniejącego użytkownika
- stwórz nowy obiekt Profile i wypełnij go danymi (np. z formularza ProfileType)
- przypisz profil do użytkownika, np. $user->setProfile($profile)
- zapisz całość do bazy.
Okazuje się, że chyba jednak nie mogę. Próby utworzenia relacji $profile w encji User, a następnie wykonanie 'doctrine:schema:update --force' kończą się tym, że na klucz główny w tabeli User zakładany jest CONSTRAINT do Profile - możecie sobie wyobrazić jakie jaja, nie mogę utworzyć wtedy ani jednego ani drugiego (bo w Profile też jest CONSTRAINT do User)...
Próbowałem kombinować z inversedBy oraz mappedBy, ale jak się pewnie domyślacie, bezskutecznie.
Tak wygląda odwołanie do User w Profile:
/** * Profile * * @ORM\Table(name="Profile") * @ORM\Entity */ class Profile { /** * @ORM\Column(name="uidx", type="integer", nullable=false) * @ORM\Id * @ORM\GeneratedValue(strategy="IDENTITY") */ private $uidx; .... inne pola ... /** * @ORM\OneToOne(targetEntity="\SP\UserBundle\Entity\User", cascade={"persist"}) * @ORM\JoinColumn(name="uidx", referencedColumnName="uidx") */ private $user; ... settery i gettery ... /** * Set user * * @param \SP\UserBundle\Entity\User $user * @return Profile */ public function setUser(\SP\UserBundle\Entity\User $user) { $this->user = $user; return $this; } /** * Get user * * @return \SP\UserBundle\Entity\User */ public function getUser() { return $this->user; } }
Tak wygląda User:
/** * User * * @ORM\Table(name="User") * @ORM\Entity * @UniqueEntity(fields="email", groups={"register"}) */ class User implements AdvancedUserInterface, \Serializable { /** * @var integer * * @ORM\Column(name="uidx", type="integer", nullable=false) * @ORM\Id * @ORM\GeneratedValue(strategy="IDENTITY") */ private $uidx; ... inne pola ... ... gettery i settery ... }
O co mi chodzi?
Chciałbym móc odwołać się np. w kontrolerze do profilu z poziomu użytkownika... nie mając jednocześnie założonego CONSTRAINT na uidx w User, czyli np:
$user = ...pobieram użytkownika; $profile = $user->getProfile();
Jest to w ogóle możliwe w SF?
A może źle kombinuje i powinienem to inaczej zaprojektować/odwzorować?
Czy dać sobie spokój i w UserRepository utworzyć zwykłego SQLa z JOIN, który pobierze mi profil np. getUserProfile() ?