Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [Symfony][Propel] własne zapytanie, obiekty
Forum PHP.pl > Forum > PHP > Frameworki
AxZx
witam

napisałem zapytanie, którego Propel sam nie wygeneruje. łączone są w nim 3 tabele. chciałbym teraz pobrać dane z dwóch tabel i w widoku mieć dostęp do tych danych poprzez odpowiedni model (odpowiedni dla tych tabel).
można to jakoś zamienić na obiekty?

chciałbym uzyskać coś takiego co zwraca metoda doSelectJoinAll.
nie mogę jednak połapać się jak takie coś samemu zmontować.
mike
Jeśli zmontowałeś jakies zapytanie, które zwraca Ci jakiś RecordSet a chciałbyś to mieć w obiektach to możesz pokombinować z
BookPeer::populateObjects(RecordSet $rs) (tu przykład dla encji Book)
AxZx
dobrze powiedziałeś: kombinować:)
bo...
metoda populateObjects przyjmuje tylko jeden parametr ResultSet $rs.
a jak w select podam kolumny z kilku tabel to nie będzie wiedział, które to są kolumny danej tabeli.

ale dzięki za podpowiedź, bo przecież można wykorzystać kod metody populateObjects odpowiednio go modyfikując:)

kombinuje dalej:)

EDIT:
no i wykombinowałem:)
dzięki mike
mike
Pokaż jak. Nie mam możliwości sprawdzenia teraz a mnie zaciekawiło.

Podejrzewam, że można to zrobić w bardzo prosty sposób.
Coś w stylu:
Kod
books
foreach (recordSet as set) {
    book = Book::populateObject(set);
    book->setAuthor(Author::opulateObject(set));

    books[] = book
}


Kurcze, żebym tylko pamiętał jak to w kodzie wygląda.

Czyżby to działało tak:
  1. <?php
  2.  
  3. $books = array();
  4. while($recordSet->next()) {
  5.    $book = new Book();
  6.    $book->hydrate($recordSet);
  7.  
  8.    $author = new Author();
  9.    $author->hydrate($recordSet);
  10.  
  11.    $book->setAuthor($author);
  12.  
  13.    $books[] = $book;
  14. }
  15.  
  16. ?>


Lecę na pamięć bo mnie ciekawość zżera biggrin.gif
athabus
Metoda hydrate ma drugi (opcjonalny) parametr $startcol, który określa numer kolumny od której zacząć tworzenie obiektu.

Czyli pobierając w jednym RS dwie tabele author i book (w tej kolejności) można zrobić np:
$book->hydrate($rs, AuthorPeer::NUM_COLUMNS + 1);

Warunek jest jeden: trzeba pobrać kolumny w takiej kolejności jak w tabeli.

Piszę z pamięci, ale kiedyś miałem dosyć zagmatwaną sytuację przy tworzeniu obiektów i właśnie w ten sposób "powoływałem" je do życia.

//EDIT
@mike - mogę się mylić, ale z tego co pamietam to po drodze trzeba jeszcze "wyzerować" rs tak żeby znów zaczął od pierwszego wiersza - coś mi tak świta. Także w twoim przypadku kod nie zadziała bo trzeba wskazać startcol i chyba wyzerować $rs.
mike
Cytat(athabus @ 15.10.2008, 16:17:11 ) *
Warunek jest jeden: trzeba pobrać kolumny w takiej kolejności jak w tabeli.
Nom. To jest spora niedogodność. W przeciwnym wypadku trzeba przepisywać metodę hydrate(). Da się ją napisać chyba tak, żeby sama szukała odpowiednich pól w wierszu.

Cytat(athabus @ 15.10.2008, 16:17:11 ) *
@mike - mogę się mylić, ale z tego co pamietam to po drodze trzeba jeszcze "wyzerować" rs tak żeby znów zaczął od pierwszego wiersza - coś mi tak świta. Także w twoim przypadku kod nie zadziała bo trzeba wskazać startcol i chyba wyzerować $rs.
No właśnie raczej nie trzeba zerować. No jak lecisz po wynikach to od razu możesz z jednego wiersza wyciągnąć dwa obiekty. Nie ma potrzeby latać dwa razy po wynikach.
AxZx
hmm ja to zrobiłem tak:

  1. <?php
  2. $q = 'select '.
  3.        implode(',', ProfilPeer::getFieldNames(BasePeer::TYPE_COLNAME)).', '.
  4.        implode(',', OgloszeniePeer::getFieldNames(BasePeer::TYPE_COLNAME)).' '.
  5.        'from kontakt
  6.        inner join ogloszenie on (ogloszenie.idprofil = kontakt.idprofil AND ogloszenie.status = 1)
  7.        inner join profil on (profil.idprofil = ogloszenie.idprofil AND profil.status = 1)
  8.        where kontakt.idprofil_wl = '.$idprofil.'
  9.        ORDER BY ogloszenie.created_at DESC
  10.        LIMIT 10';
  11.        
  12.        $con = Propel::getConnection();
  13.        $rs = $con->executeQuery($q, ResultSet::FETCHMODE_NUM);
  14.  
  15.        $results = array();
  16.        
  17.        $startcol2 = (ProfilPeer::NUM_COLUMNS - ProfilPeer::NUM_LAZY_LOAD_COLUMNS) + 1;
  18.        
  19.        $ProfilOmClass = ProfilPeer::getOMClass();
  20.        $profilCls = Propel::import($ProfilOmClass);
  21.        
  22.        $ogloszenieOmClass = OgloszeniePeer::getOMClass();
  23.        $ogloszenieCls = Propel::import($ogloszenieOmClass);
  24.        
  25.        $i=0;
  26.        while($rs->next()) {        
  27.            
  28.            $profil = new $profilCls();
  29.            $profil->hydrate($rs);
  30.            
  31.            $ogloszenie = new $ogloszenieCls();
  32.            $ogloszenie->hydrate($rs, $startcol2);
  33.            
  34.            $results[$i]['profil'] = $profil;
  35.            $results[$i]['ogloszenie'] = $ogloszenie;
  36.  
  37.            $i++;
  38.        }
  39.        
  40.        return $results;
  41. ?>


w widoku dostęp do tych obiektów mam tak:
  1. <?php foreach($ogloszenia as $aOgloszenie): ?>
  2.        <div>
  3.            <?php
  4.            $profil = $aOgloszenie['profil'];
  5.            $ogloszenie = $aOgloszenie['ogloszenie'];
  6.            ?>
  7. </div>
  8.    <?php endforeach; ?>
athabus
Faktycznie mike masz racje - nie spojrzałem dokładnie w twój kod - lecisz jedną pętlą wszystko więc nie trzeba zerować $rs. Także jeśli dasz $startcolumn to powinno działać.
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.