Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [SF][SF2]Relacja ManyToMany, Dodatkowe pole w tabeli łączącej
mimol
post 4.01.2013, 11:22:36
Post #1





Grupa: Zarejestrowani
Postów: 247
Pomógł: 5
Dołączył: 10.12.2007

Ostrzeżenie: (0%)
-----


Witam.
Mam dwie tabele: Movie, Media, połączone są relacją ManyToMany, więc tak naprawdę mam jeszcze tabele movie__has_media.
Chciałbym aby w tabeli łączącej(movie__has_media) Było dodatkowe pole type(będzie przechowywać typ obrazka).
Nie chcę mieć tego w tabeli media(nie zawsze typ obrazka jest wymagany)
Czy da się takie coś osiągać. Jeśli tak to jak?
Jak potem wyświetlić typ obrazka?(Nie jest on przecież ani w tabeli media, ani w tabeli movie)
===================
Domyślam się, że można zrobić jeszcze
Movie , movie_has_type, movie_has_type_has_media, media, Jednak uważam to za gorsze rozwiązanie....
Go to the top of the page
+Quote Post
thek
post 4.01.2013, 12:34:38
Post #2





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




To co chcesz osiągnąc to jedna z "bolączek" SF2, a konkretniej używanej przez ten FW Doctrine2. Da się osiągnąć poprzez ręcznie utworzoną encję tabeli łączącej na zasadzie takich relacji:
Pierwsza tabela: OneToMany z łączącą,
Druga tabela: OneToMany z łączącą
Łącząca tabela: ManyToOne z pierwszą i ManyToOne z drugą

Wtedy w łączącej możesz sobie dawać różne własności, takie jak wspomniany type.

Więcej dokładniejszych opisów co i jak masz w google przy: many to many with parameter.

EDIT: Ogólnie dla Twojego przypadku zastanawiałbym się, czy jednak nie pchnąć tego do Media z opcją ustawienia type na null. Naprawdę mniej babrania się z tym. Łączeniowa z parametrem w SF2 nie jest fajna do obsługi z racji konieczności pisania wielu dodatkowych metod do obsługi, najczęściej w klasach repozytoriów dla danej encji. Media z reguły sam narzuca jakiego jest typu, nie da się tego wyrzucić poza nawias. Zawsze ma ścisłe przypisanie. Gdyby bylo inaczej, miało by to sens. Przykład? Aplikacja wielojęzyczna. Różni userzy mogą mieć kilka po języków przypisanych, więc jest to typowe many-2-many. Mają jednak określony język defaultowy. Gdyby był jeden dla wszystkich w Languages bezpośrednio, pakowalibysmy to tam do srodka. Ale kazdy user może sobie go na dowolny inny spośród dostępnych ustawić, co z automatu ustawiało by go wszystkim innym userom w systemie wink.gif Albo więc informację o defaultowym pakujemy do Usera bezpośrednio, albo tworzymy tabelę łączącą z językami i tam jako parametr jednego ustawimy na true, co sprawi, iż staje się domyślnym.
Powód edycji: [thek]: Mała uwaga


--------------------
Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
Go to the top of the page
+Quote Post
mimol
post 4.01.2013, 13:31:39
Post #3





Grupa: Zarejestrowani
Postów: 247
Pomógł: 5
Dołączył: 10.12.2007

Ostrzeżenie: (0%)
-----


Nie wiem czy kiedykolwiek używałeś https://github.com/sonata-project/SonataMediaBundle
Tam tabela media__gallery_media (łącząca) ma te dodatkowe pola o których mówiłem. Jednak nie potrafię znaleźć Jak to jest połączone z doctrinem...
(Przeglądałem foldery Entity/ Model)
Może to jest jakoś w łatwiejszy sposób rozwiązane?

Hmm znalazłem, jest to rozwiązane tak jak mówiłeś wcześniej

Ten post edytował mimol 4.01.2013, 16:09:43
Go to the top of the page
+Quote Post
misi3kk
post 4.01.2013, 19:34:03
Post #4





Grupa: Zarejestrowani
Postów: 26
Pomógł: 4
Dołączył: 14.05.2010

Ostrzeżenie: (0%)
-----


Mam u siebie podobny kod, oparty właśnie o SonataMediaBundle.

Rozwiązali to tak jak napisał wyżej @thek - osobne entity do łączenia i w nim relacja ManyToOne, a w dwóch pozostałych OneToMany.
Jeśli ktoś nie wierzy, to zapraszam do lektury pliku DependencyInjection/SonataMediaExtension.php wspomnianego wcześniej bundla (aktualnie od 170 linijki jest mapowanie Doctrine).

Jest z tym cała masa pracy, samego mapowania naszukałem się bardzo bardzo długo, ale da się to zrobić wink.gif Problem głównie był z SonataAdminBundle i usuwaniem powiązań.


--------------------
Accesto.pl
Go to the top of the page
+Quote Post
m44
post 4.01.2013, 21:50:36
Post #5





Grupa: Zarejestrowani
Postów: 63
Pomógł: 10
Dołączył: 16.11.2008

Ostrzeżenie: (0%)
-----


Doctrine jako ORM dostarcza tylko kilka podstawowych rozwiązań, które da się wykorzystać na szybko bez zbędnego oprogramowywania. Nikt nie mówił, że ORM to narzędzie idealne wink.gif
Jeśli Twój schemat bazy danych wymaga czegoś więcej niż opisanie całości w prostych relacjach, które znajdziesz w dokumentacji Doctrine, to musisz się trochę więcej "napracować".
Twój projekt wymaga, aby dołożyć do tabeli m:n dodatkową kolumnę, nie da się tego obejść inaczej, jak zasugerował thek i poprzednicy. Czy często spotykane, proste wiele do wielu sprowadzić do relacji jeden do wielu i wiele do jednego.
Go to the top of the page
+Quote Post
HansKlops
post 8.01.2013, 00:52:59
Post #6





Grupa: Zarejestrowani
Postów: 1
Pomógł: 0
Dołączył: 8.01.2013

Ostrzeżenie: (0%)
-----


Witajcie,

mam problem właśnie z takim rozwiązaniem, a konkretnie z Sonatą, której używam do admina. Używając przykładu podanego w tym wątku chciałbym przy edycji Movie mieć możliwość edycji Mediów powiązanych z tym konkretnym Movie wraz z edycją dodatkowych pól trzymanych w tabeli łączącej.
Zakładam, że definicje w Doctrine mam dobrze, tabele się generują poprawnie kiedy użyję doctrine:schema:update.

Kod w MovieAdmin:

Kod
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->add('name')
            ->add('media', 'sonata_type_collection', array(
                'by_reference' => false
            ), array(
                'edit' => 'inline',
                'inline' => 'table',
                'sortable'  => 'sortOrder',
            ))
      ;
    }

Podczas edycji Movie wyświetla się wszystko OK, jest lista powiązanych mediów wraz z dodatkowymi polami, problem jest gdy chcę dodać nowe media. Klikam na przycisk "add new" znajdujący się pod listą, wpisuję co trzeba, klikam "save" i dostaję błąd:
Cytat
Entity of type MySite\MyBundle\Entity\MovieHasMedia is missing an assigned ID for field 'movie'. The identifier generation strategy for this entity requires the ID field to be populated before EntityManager#persist() is called. If you want automatically generated identifiers instead you need to adjust the metadata mapping accordingly.

Jak sobie z tym poradzić? Niedawno zacząłem przygodę z SF2 i mnie zblokowało. sciana.gif

Dzięki wielkie za każdą pomoc.

Ten post edytował HansKlops 8.01.2013, 00:54:08
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 6.06.2024 - 17:19