![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 38 Pomógł: 5 Dołączył: 10.05.2009 Ostrzeżenie: (0%) ![]() ![]() |
Cześć.
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:
Tak wygląda User:
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:
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() ? Ten post edytował r4nd4ll 16.05.2013, 10:11:14 |
|
|
![]() |
![]()
Post
#2
|
|
![]() Grupa: Zarejestrowani Postów: 879 Pomógł: 189 Dołączył: 14.06.2006 Skąd: Bytom Ostrzeżenie: (0%) ![]() ![]() |
Tylko czemu się dziwisz, że tworzy Tobie tabele z kluczami obcymi skoro tego chcesz? Wystarczy, żeby kolumna odpowiadająca za profil w tabeli użytkownika mogła przyjmować wartość null. W tym celu musisz w encji User dla właściwości profil dodać annotacje JoinColumn z kluczem nullable o wartości true. Szczególy w dokumentacji.
|
|
|
![]()
Post
#3
|
|
Grupa: Zarejestrowani Postów: 38 Pomógł: 5 Dołączył: 10.05.2009 Ostrzeżenie: (0%) ![]() ![]() |
Właśnie o to chodzi, że w tabeli profil nie ma kolumny odpowiadajacej za profil.
Jest jeden klucz główny uidx w User i relacja 1-1 do Profile, gdzie ten klucz uidx jest jednoczesnie kluczem glownym i obcym. User: uidx ... Profile: uidx ... I teraz chodzi mi o to, czy jest szansa, żebym mógł odwoływać się z poziomu User do Profile, np. tak $user->getProfile() ? Mając analogiczną sytuację, w Yii wyglądało to tak:
... tym sposobem mogłem zrobić zarówno:
Czy w Doctrine jestem w stanie uzyskać podobny efekt, czy powinienem dać sobie spokój i kombinować inaczej? Ten post edytował r4nd4ll 16.05.2013, 09:50:35 |
|
|
![]()
Post
#4
|
|
![]() Grupa: Zarejestrowani Postów: 879 Pomógł: 189 Dołączył: 14.06.2006 Skąd: Bytom Ostrzeżenie: (0%) ![]() ![]() |
Cytat Właśnie o to chodzi, że w tabeli profil nie ma kolumny odpowiadajacej za profil. Pisałem o tabeli użytkowników. Cytat Czy w Doctrine jestem w stanie uzyskać podobny efekt, czy powinienem dać sobie spokój i kombinować inaczej? Tak, jesteś w stanie. Na przyszłość jak przedstawiasz relacje to najlepiej jak przedstawisz jej obie strony. Oprócz Profile przydałby się jeszcze User. |
|
|
![]()
Post
#5
|
|
Grupa: Zarejestrowani Postów: 38 Pomógł: 5 Dołączył: 10.05.2009 Ostrzeżenie: (0%) ![]() ![]() |
Wyedytowałem pierwszy post, jest i User.
A mógłbyś mnie trochę nakierować jak się do tego zabrać? Zakładając, że uidx w Profile nie może być nullable - toż to klucz główny. |
|
|
![]()
Post
#6
|
|
![]() Grupa: Zarejestrowani Postów: 879 Pomógł: 189 Dołączył: 14.06.2006 Skąd: Bytom Ostrzeżenie: (0%) ![]() ![]() |
Cytat Zakładając, że uidx w Profile nie może być nullable - toż to klucz główny. Nie mam już pomysłu jak mam napisać żebyś zrozumiał, że chodzi nie o profil a o użytkownika Po zamieszczeniu encji User od razu jest wiadome, że zrobiłeś relację jednokierunkową, a chcesz z niej skorzystać jak z dwukierunkowej. Jak już to zmienisz to w encji User dla pola profile ustaw nullable. Inna sprawa, że chyba źle do tego podchodzisz. W encji Profile chcesz mieć klucz główny uidx z automatycznie generowaną wartością a dodatkowo chcesz, żeby jeszcze też było to kluczem obcym do innej tabeli. Najprostsze rozwiązanie to: klucz główny dla Profile to jedno pole (najlepiej standardowo id) a drugie pole user z relacją do opdowiedniej encji (Doctrine sam sobie utworzy kolumnę dla tej relacji). Przy takim rozwiązaniu zachowujesz konwencje a to jest po prostu wygodne. Możesz usunąć to uidx z Profile i dodać adnotacje @Id do pola user (szczegóły). |
|
|
![]()
Post
#7
|
|
Grupa: Zarejestrowani Postów: 38 Pomógł: 5 Dołączył: 10.05.2009 Ostrzeżenie: (0%) ![]() ![]() |
Po zamieszczeniu encji User od razu jest wiadome, że zrobiłeś relację jednokierunkową, a chcesz z niej skorzystać jak z dwukierunkowej. Jak już to zmienisz to w encji User dla pola profile ustaw nullable. Wkleiłem to co przywróciłem, gdy próby z dwukierunkową relacją mnie zawiodły (jedyne co "jakoś" działało).. W encji Profile chcesz mieć klucz główny uidx z automatycznie generowaną wartością To Generated jakoś się tam zaplątało, oczywiście nie miał być automatycznie generowany, za to miał być odpowiednikiem uidx z User. Mniejsza z tym, dodałem osobny klucz glowny $profidx do Profile. Posiłkując się tym linkiem: http://docs.doctrine-project.org/projects/...e-bidirectional mam teraz tak:
I teraz:
Stwierdziłeś, że to co chcę osiągnąć jest możliwe, więc męczę się z tą przeklętą relacją już pół dnia i jestem niemalże tam gdzie byłem.. Będę wdzięczny jeśli chciałoby Ci się na to zerknąć jeszcze raz. /// EDIT Zmodyfikowałem metodę User setProfile:
I wygląda na to, że działa, w obie strony ![]() Pytanie tylko, czy takie podejście jest prawidłowe i nie mieszam tym za bardzo?? Ten post edytował r4nd4ll 16.05.2013, 17:50:52 |
|
|
![]() ![]() |
![]() |
Aktualny czas: 21.08.2025 - 22:48 |