Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [Symfony] relacja wiele do wielu w obrębie jednego obiektu
Forum PHP.pl > Forum > PHP > Frameworki
Foxx
Witajcie, mam obiekt "produkt". Każdy produkt może mieć kilka powiązanych z nim tematycznie produktów. Chciałbym po prostu wyświetlać na karcie produktu te, które są z nim powiązane. No więc zrobiłem tabelę relacji wiele do wielu:
Kod
produkt_produkt:
    produkt_id:             { type: integer, foreignTable: produkt, foreignReference: id, required: true, primaryKey: true, onDelete: cascade }
    powiazany_id:           { type: integer, foreignTable: produkt, foreignReference: id, required: true, primaryKey: true, onDelete: cascade }


Wygenerowałem moduł produkt_produkt i chciałem wywołać pole w adminie:
Kod
"Powiązane produkty":          [ produkt_produkt_list ]


Ale otrzymałem błąd:
Kod
Widget "produkt_produkt_list" does not exist.

Pomyślałem, że to może konflikt nazw i zmieniłem nazwę tabeli na produkt_powiazany, otrzymałem ten sam błąd. Gdy robię taką relacyjną tabelę dla dwóch różnych obiektów wszystko jest w porządku. W związku z tym pytam: czy nie da się zrobić relacji wiele do wielu w obrębie jednego obiektu? Jeżeli się da to będę wdzięczny za wskazówki. Jeżeli się nie da to będę wdzięczny za podpowiedzi jak zrealizować takie coś. Pozdrawiam.
BigB
Na 50% da się zrobić relację wiele do wielu biggrin.gif
Mogę się mylić, ale jeśli Ci wywala, że taki widget nie istnieje, a przecież istnieje, to może rzeczywiście coś z tą nazwą? Coś mi się kojarzy, że symfony usuwa _ (underscore) z nazw modeli itp. więc może spróbuj nazwać tabelę "powiazania" i wtedy dać:
  1. "Powiązane produkty": [ powiazania_list ]


Nie gwarantuję nic, może to totalna bzdura, ale tak mi jakoś zapadły w pamięć te podkreślniki winksmiley.jpg
Foxx
Znowu trafiłem na ten problem i teraz już muszę to jakoś rozwiązać. Bardzo potrzebuję relacji do samego siebie - nie pojmuję dlaczego to dla Symfony mógłby być problem. Na przykład: ulubieni użytkownicy, czyli użytkownik ustawia innych użytkowników jako obserwowanych. Robię więc tabelę:

Kod
obserwacja:
    obserwujacy: { type: integer, foreignTable: uzytkownik, foreignReference: id, required: true, primaryKey: true, onDelete: cascade }
    obserwowany: { type: integer, foreignTable: uzytkownik, foreignReference: id, required: true, primaryKey: true, onDelete: cascade }


No i dostaję komunikat "Widget "obserwacja_list" does not exist."...
Czy popełniam jakiś błąd?
Gribo
pokarz co masz w pliku ProduktProdukBaseForm bo tak na ślepo ciężko poradzić
Foxx
Trochę pozmieniałem przykłady bo ciągle staram się to rozpracować. Teraz tabela wygląda tak:

Kod
uzytkownik_obserwacja:
    uzytkownik_id:            { type: integer, foreignTable: uzytkownik, foreignReference: id, required: true, primaryKey: true, onDelete: cascade }
    obserwowany_id:           { type: integer, foreignTable: uzytkownik, foreignReference: id, required: true, primaryKey: true, onDelete: cascade }


A klasa BaseUzytkownikObserwacjaForm tak:

  1. class BaseUzytkownikObserwacjaForm extends BaseFormPropel
  2. {
  3. public function setup()
  4. {
  5. $this->setWidgets(array(
  6. 'uzytkownik_id' => new sfWidgetFormInputHidden(),
  7. 'obserwowany_id' => new sfWidgetFormInputHidden(),
  8. ));
  9.  
  10. $this->setValidators(array(
  11. 'uzytkownik_id' => new sfValidatorPropelChoice(array('model' => 'Uzytkownik', 'column' => 'id', 'required' => false)),
  12. 'obserwowany_id' => new sfValidatorPropelChoice(array('model' => 'Uzytkownik', 'column' => 'id', 'required' => false)),
  13. ));
  14.  
  15. $this->widgetSchema->setNameFormat('uzytkownik_obserwacja[%s]');
  16.  
  17. $this->errorSchema = new sfValidatorErrorSchema($this->validatorSchema);
  18.  
  19. parent::setup();
  20. }
  21.  
  22. public function getModelName()
  23. {
  24. return 'UzytkownikObserwacja';
  25. }
  26. }
Gribo
a weś wygeneruj sobie model za pomocą polecenia
  1. symfony propel:generate-module frontend jakasnazwa UzytkownikObserwacja


i zobacz efekt bo z tego co widze nie ma taiego pola ty chcesz costam_list. Takie pole jest generowane dla modeli uzytkownik sprawdź sobie to podgladajac plik BaseUzytkownikForm i tam bedzie pole uzytkownik_opserwacja_list.
Foxx
A więc tak: naprawdę się temu przyjrzałem i stwierdzam, że robiąc wszystko identycznie jak dla każdej innej relacji wiele-do-wielu i próbując wyświetlić w wygenerowanym backendzie pole uzytkownik_obserwacja_list otrzymuję komunikat o braku tego widgetu (przy relacji wiele-do-wielu ale dwóch różnych obiektów wszystko działa idealnie).

Patrząc na zawartość pliku BaseUzytkownikForm.class.php (thx Gribo) rzeczywiście nie ma tego pola. Jak gdyby Symfony nie chciało wygenerować tych linijek kodu dla relacji w obrębie tego samego obiektu.

Próbowałem rozwiązać ten problem po prostu tworząc brakujący widget w pliku UzytkownikForm.class.php:

  1. $this->setWidgets(array(
  2. 'uzytkownik_obserwacja_list' => new sfWidgetFormPropelChoiceMany(array('model' => 'Uzytkownik')),
  3. ));
  4.  
  5. $this->setValidators(array(
  6. 'uzytkownik_obserwacja_list' => new sfValidatorPropelChoiceMany(array('model' => 'Uzytkownik', 'required' => false)),
  7. ));
  8.  
  9. # i jeszcze kosmetyka:
  10. $this->widgetSchema['uzytkownik_obserwacja_list']->setOption('renderer_class', 'sfWidgetFormSelectDoubleList');
  11. $this->widgetSchema['uzytkownik_obserwacja_list']->setOption('renderer_options', array('label_associated' => 'Obserwowani', 'label_unassociated' => 'Nieobserwowani'));


Ale ten kod nie działa. Double List się pojawia prawidłowo i nawet wyświetla w środku rekordy ale nie da się stworzyć żadnej relacji.

Martwi mnie , że nie zotało to stworzone automatycznie.
Może ktoś spróbuje wykonać taki eksperyment i stworzy sobie jakąkolwiek relację wiele do wielu w obiektu do samego siebie?
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.