Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [Symfony][Doctrine] Problem z prostym złączeniem.
Forum PHP.pl > Forum > PHP > Frameworki
m44
Korzystam z pluginu sfDoctrineGuardPlugin. Dodatkowo mam w bazie tabelę przechowującą teksty literackie użytkowników, powiązaną z sfGuardUser:

Kod
writing:
  actAs:
    Taggable: ~
    Timestampable: ~
    Sluggable:
      fields: [title]
      name: title_slug
      canUpdate: true
      unique: false
  columns:
    user_id:
      type: integer
    title:
      type: string(255)
    title_slug:
      type: string(255)
    content:
      type: clob
  relations:
    User:
      class: sfGuardUser
      type: one
      foreignType: many
      foreignAlias: Writings
      local: user_id
      foreign: id
      onDelete: CASCADE
  options:
    collate: utf8_unicode_ci
    charset: utf8
  indexes:
    writings_index:
      fields: [created_at, updated_at, title_slug]


Jeden użytkownik może być autorem wielu tekstów, a jeden tekst posiada jednego użytkownika (autora). Próbuję "dobrać się" do wszystkich tekstów użytkownika nie za pomocą zwykłego getWriters() w sfGuardUser, ponieważ zależy mi na istnieniu dodatkowej kolumny - nazwy użytkownika. W tym celu dopisałem metodę w sfGuardPlugin:

  1. class sfGuardUser extends PluginsfGuardUser
  2. {
  3. public function activation()
  4. {
  5. $this->setIsActive(1);
  6. $this->save();
  7.  
  8. return $this;
  9. }
  10.  
  11. public function getWritingsWithUsername()
  12. {
  13. if($this->exists())
  14. {
  15. return $this->getTable()->createQuery('u')
  16. ->innerJoin('u.Writings w ON w.user_id = ?', array($this->getId()))
  17. //->setHydrationMode(Doctrine::HYDRATE_NONE)
  18. ->execute();
  19. }
  20. return FALSE;
  21. }
  22. }


Niestety Doctrine zwraca mi zawsze tylko jeden rekord , pomimo że czysty SQL w konsoli PhpMyAdmin zwraca ich tyle, ile jest w bazie. Co ciekawe, jeśli wymuszę zachowanie na Doctrine::HYDRATE_NONE, to metoda użytkownika zwraca tyle rekordów co czysty SQL.

Czy ktoś wie dlaczego Doctrine zwraca tylko jeden rekord?
olekbiker
Doctrine najprawdopodobniej zwraca prawidłowy wynik- jednak w postaci obiektów. Obiekt User zawiera wiele obiektów pokrewnych tabeli Writing.
Można to samemu zauważyć stosując hydratację do tabeli (Doctrine_Core::HYDRATE_ARRAY) i wyświetlając wynik tej operacji.

Mam jeszcze jedno pytanie dotyczące wklejonego kodu: za co odpowiada zachowanie "taggable"? Szukałem w dokumentacji doctrine i nie znalazłem tego zachowania wśród standardowych.
m44
Miałeś rację, wszystko jest w obiekcie. Co ciekawe w innym miejscu używałem Doctrine poprawnie, a dostęp był niemalże identyczny. Chyba muszę zrobić sobie przerwę na herbatę. winksmiley.jpg

Co do taggable, to jest to dodatkowy plugin.
olekbiker
Jeśli mogę jeszcze coś zasugerować. W mojej opinii niepotrzebne jest w ogóle złączenie w metodzie getWritingsWithUsername. Skoro warunkiem złączenia staje się userId, to przecież znacznie prościej jest wykonać:

  1. public function getWritingsWithUsername()
  2. {
  3. if($this->exists())
  4. {
  5. return Doctrine_Query::create()
  6. ->from('Writing')
  7. ->where('user_id = ?', $this->getId())
  8. ->execute(array(), Doctrine_Core::HYDRATE_ARRAY);
  9. }
  10. return FALSE;
  11. }


Powyższy przykład posiada "podwójną optymalizację" - po pierwsze nie łączy tabel, a jedynie wyszukuje po indeksie, a po drugie nie wykonuje hydratacji do obiektu. Warto jednak pamiętać, że hydratacja do tablicy stosowana jest w momencie odczytu danych i braku konieczności wykonywania na nich operacji zmieniających stan obiektów (update(), save()).
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.