Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [Symfony][Doctrine] Problem z prostym złączeniem.
m44
post
Post #1





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

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


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?
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 3)
olekbiker
post
Post #2





Grupa: Zarejestrowani
Postów: 6
Pomógł: 0
Dołączył: 8.09.2009

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


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.
Go to the top of the page
+Quote Post
m44
post
Post #3





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

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


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ę. (IMG:style_emoticons/default/winksmiley.jpg)

Co do taggable, to jest to dodatkowy plugin.
Go to the top of the page
+Quote Post
olekbiker
post
Post #4





Grupa: Zarejestrowani
Postów: 6
Pomógł: 0
Dołączył: 8.09.2009

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


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()).
Go to the top of the page
+Quote Post

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

 



RSS Aktualny czas: 22.08.2025 - 19:44