Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [SF][Symfony2][SF2] Problem z otrzymywaniem danych z bazy
Forum PHP.pl > Forum > PHP > Frameworki
pav
Witam,
Mam mały problem z wyświetleniem danych. Otóż chciałbym,aby na stronie wyswietliły się po 9 zwierząt (ich imiona, zdjecie oraz id, które przeniesie do szczegułów danego zwierzaka).Każdymu ze zwierzat ma wyświetlić po 1 zdjęciu.
Dla zilustrowania link do zdjecia


Są dwie tabele:
Zwierzeta: idzwierzatka, imie, opis itd.
Zdjecia: idzdjecia, nazwa_pliku, idzwierzatka itd.

Chodzi mi o to, aby wyciągnął z bazy imiona zwierząt i każdemu ze zwierząt dał po 1 zdjęciu jako miniaturkę.


Wydaje mi się, że powinienem to zrobić inner join'em, dlatego też taki pokaże kod:

Controller:

Kod
   public function kotyAction(Request $request)
    {
        $query = $this->getDoctrine()->getManager()
          ->createQuery("
                        SELECT z, w
                        FROM MultimediaAccountBundle:Zdjecia z
                        INNER JOIN MultimediaAccountBundle:Zwierze w
                        WHERE z.idzwierzatka LIKE w.idzwierzatka AND w.kot LIKE '1'
                        ")
                
          ->getResult();

          
       var_dump($query );

        $paginator  = $this->get('knp_paginator');
        $pagination = $paginator->paginate(
            $query,
            $this->get('request')->query->get('page', 1)/*page number*/,
            9/*limit per page*/
        );
          

        return $this->render('MultimediaStronaBundle:Koty:koty.html.twig', array(
            'pagination' => $pagination,
            'query' => $query
                ));

          
    }



Strona w twig :
Kod
<table>
    {# table body #}
    {% for zwierze in pagination %}
     {% if loop.index is odd %} {% endif %}
    <div class="row-fluid">
    <ul class="thumbnails">
            {% if loop.index0 is divisibleby(3) and loop.index0 != 0 %}
    </ul>
        </div>
        <div class="row-fluid">
            <ul class="thumbnails">
                    {% endif %}
                <li class="span4">
                    <div class="thumbnail">
                        <div class="caption">
                            <center>
                                
                            <h2>{#{ zwierze.idzwierzatka }#}{{ zwierze.imie }}</h2>
                                {#{ dump(pagination) }#}

                                </center>
                            <p><a  href="{{ url('KotSzczegoly', {'idzwierzatka':  zwierze.idzwierzatka }) }}">
                                   {% for zdjecie in query %}
                                        <img src="{{ asset('zdjecia/zwierzeta/') }}{{ zdjecie.imageName }}" class="img-rounded" />
                                   {% endfor %}      

                                </p>
                                <center>
                             <p><a class="btn" href="{{ path('KotSzczegoly', {'idzwierzatka':  zwierze.idzwierzatka }) }}">Zobacz go &raquo;</a></p>
                                </center>  
                        </div>
                    </div>
               </li>
              {% endfor %}
              
            </ul>
        </div>
        <div class="navigation">
            {{ knp_pagination_render(pagination, null, {}, {'alignment': 'center'}) }}
        </div>
</table>



Numeracja stron jest z KNP Paginator. Po takim kodzie strona wygląda:
wyglada tak...


A var dump query:
Kod
array (size=9)
  0 =>
    object(Multimedia\AccountBundle\Entity\Zdjecia)[2413]
      private 'idzdjecia' => int 8
      protected 'image' =>
        object(Symfony\Component\HttpFoundation\File\File)[2481]
      protected 'imageName' => string '517ee52260453.jpeg' (length=18)
      private 'idzwierzatka' => int 2
      public 'path' => null
  1 =>
    object(Multimedia\AccountBundle\Entity\Zwierze)[2458]
      protected 'idzwierzatka' => int 2
      protected 'imie' => string 'Maciuś' (length=7)
      protected 'rasa' => null
      protected 'kot' => boolean true
      protected 'pies' => boolean false
      protected 'opis' => string 'Był to bardzo mały kotek, o ślicznych czarno-białych łapkach.' (length=66)
      protected 'data_urodzenia' =>
        object(DateTime)[2479]
          public 'date' => string '2013-03-04 00:00:00' (length=19)
          public 'timezone_type' => int 3
          public 'timezone' => string 'UTC' (length=3)
      protected 'data_rejestracji' =>
        object(DateTime)[2480]
          public 'date' => string '2013-03-19 00:00:00' (length=19)
          public 'timezone_type' => int 3
          public 'timezone' => string 'UTC' (length=3)
      protected 'zdjecia' =>
        object(Doctrine\ORM\PersistentCollection)[2495]
          private 'snapshot' =>
            array (size=0)
              ...
          private 'owner' =>
            &object(Multimedia\AccountBundle\Entity\Zwierze)[2458]
          private 'association' =>
            array (size=15)
              ...
          private 'em' =>
            object(Doctrine\ORM\EntityManager)[293]
              ...
          private 'backRefFieldName' => string 'zwierze' (length=7)
          private 'typeClass' =>
            object(Doctrine\ORM\Mapping\ClassMetadata)[2459]
              ...
          private 'isDirty' => boolean false
          private 'initialized' => boolean false
          private 'coll' =>
            object(Doctrine\Common\Collections\ArrayCollection)[2483]
              ...
  2 =>
    object(Multimedia\AccountBundle\Entity\Zdjecia)[2457]
      private 'idzdjecia' => int 9
      protected 'image' =>
        object(Symfony\Component\HttpFoundation\File\File)[2501]
      protected 'imageName' => string '517fd6a07a5d6.jpeg' (length=18)
      private 'idzwierzatka' => int 2
      public 'path' => null
  3 =>
    object(Multimedia\AccountBundle\Entity\Zdjecia)[2499]
      private 'idzdjecia' => int 10
      protected 'image' =>
        object(Symfony\Component\HttpFoundation\File\File)[2503]
      protected 'imageName' => string '518699dff14c5.jpeg' (length=18)
      private 'idzwierzatka' => int 2
      public 'path' => null
  4 =>
    object(Multimedia\AccountBundle\Entity\Zdjecia)[2504]
      private 'idzdjecia' => int 11
      protected 'image' =>
        object(Symfony\Component\HttpFoundation\File\File)[2506]
      protected 'imageName' => string '51869a01e8e29.jpeg' (length=18)
      private 'idzwierzatka' => int 2
      public 'path' => null
  5 =>
    object(Multimedia\AccountBundle\Entity\Zdjecia)[2500]
      private 'idzdjecia' => int 12
      protected 'image' =>
        object(Symfony\Component\HttpFoundation\File\File)[2508]
      protected 'imageName' => string '51869a3d13cc6.jpeg' (length=18)
      private 'idzwierzatka' => int 2
      public 'path' => null
  6 =>
    object(Multimedia\AccountBundle\Entity\Zdjecia)[2502]
      private 'idzdjecia' => int 13
      protected 'image' =>
        object(Symfony\Component\HttpFoundation\File\File)[2510]
      protected 'imageName' => string '518cca6b9c462.jpeg' (length=18)
      private 'idzwierzatka' => int 2
      public 'path' => null
  7 =>
    object(Multimedia\AccountBundle\Entity\Zdjecia)[2507]
      private 'idzdjecia' => int 15
      protected 'image' =>
        object(Symfony\Component\HttpFoundation\File\File)[2512]
      protected 'imageName' => string '51960585745bf.jpeg' (length=18)
      private 'idzwierzatka' => int 4
      public 'path' => null
  8 =>
    object(Multimedia\AccountBundle\Entity\Zwierze)[2509]
      protected 'idzwierzatka' => int 4
      protected 'imie' => string 'aaaaaaaaa' (length=9)
      protected 'rasa' => null
      protected 'kot' => boolean true
      protected 'pies' => boolean false
      protected 'opis' => string 'aaaaas' (length=6)
      protected 'data_urodzenia' =>
        object(DateTime)[2460]
          public 'date' => string '2009-05-18 00:00:00' (length=19)
          public 'timezone_type' => int 3
          public 'timezone' => string 'UTC' (length=3)
      protected 'data_rejestracji' =>
        object(DateTime)[2478]
          public 'date' => string '2008-01-01 00:00:00' (length=19)
          public 'timezone_type' => int 3
          public 'timezone' => string 'UTC' (length=3)
      protected 'zdjecia' =>
        object(Doctrine\ORM\PersistentCollection)[2511]
          private 'snapshot' =>
            array (size=0)
              ...
          private 'owner' =>
            &object(Multimedia\AccountBundle\Entity\Zwierze)[2509]
          private 'association' =>
            array (size=15)
              ...
          private 'em' =>
            object(Doctrine\ORM\EntityManager)[293]
              ...
          private 'backRefFieldName' => string 'zwierze' (length=7)
          private 'typeClass' =>
            object(Doctrine\ORM\Mapping\ClassMetadata)[2459]
              ...
          private 'isDirty' => boolean false
          private 'initialized' => boolean false
          private 'coll' =>
            object(Doctrine\Common\Collections\ArrayCollection)[2515]
              ...



Proszę o pomoc.

Dziękuję.
pav
Dziękuję za odpowiedź.
Już zmieniłem w controllerze z normalnego sql'owkiego zapytania na buildera:

Kod
          $query = $this->getDoctrine()->getManager()
            ->createQueryBuilder()
            ->select(array('z','w'))  
            ->from('MultimediaAccountBundle:Zdjecia', 'z')
            ->join('MultimediaAccountBundle:Zwierze', 'w')
            ->where('w.kot = 1 ')    
            ->getQuery()
            ->setMaxResults(1)    
            ->getResult();



Może źle napisałem.
Są dwie tabele:
Zwierzeta: idzwierzatka, imie, opis itd.
Zdjecia: idzdjecia, nazwa_pliku, idzwierzatka itd.

Chodzi mi o to, aby wyciągnął z bazy imiona zwierząt i każdemu ze zwierząt dał po 1 zdjęciu jako miniaturkę.

Już dodałem do pierwszego postu.
pav
Cytat
więc $obiekt->getImie() itp
a do zdjęcia $obiekt->getZdjecie()->getNazwaPliku()
konkretne metody zależą od nazw pól jakie dałeś w encjach


Tak więc w twigu jeśli chce używać danych przekazanych przez kontroller to muszę forem ? Np.
Kod
{% for zdjecie in query %}
<img src="{{ asset('zdjecia/zwierzeta/') }}{{ zdjecie.imageName }}" class="img-rounded" />
  {% endfor %}


Problem teraz w tym, ze nazwy zwierząt się wypisuja idalnie, ale zamiast 1 zdjecia na danym zwierzatku to wyswiwetlaja sie wszystkie u kazdego. Tak więc musiałem dac setMaxResults na 1, tylko teraz pojawia sie tylko 1 zdjecie.

Przerobiony kod:
Kod
public function kotyAction(Request $request)
    {
         $zwierzatka = $this->getDoctrine()->getManager()
          ->createQuery("
                        SELECT w
                        FROM MultimediaAccountBundle:Zwierze w
                        WHERE w.kot LIKE '1'
                        ")
                
          ->getResult();

          $query = $this->getDoctrine()->getManager()
            ->createQueryBuilder()
           // ->select(array('z','w'))
            ->select('z')      
            ->from('MultimediaAccountBundle:Zdjecia', 'z')
            ->innerjoin('MultimediaAccountBundle:Zwierze', 'w')
            ->where('w.kot = 1 ')    
            ->getQuery()
            ->setMaxResults(1)    
            ->getResult();
          
       var_dump($query);

        $paginator  = $this->get('knp_paginator');
        $pagination = $paginator->paginate(
            $zwierzatka,
            $this->get('request')->query->get('page', 1)/*page number*/,
            9/*limit per page*/
        );
          

        return $this->render('MultimediaStronaBundle:Koty:koty.html.twig', array(
            'pagination' => $pagination,
            'query' => $query
                ));

          
    }


Mogę dać link do git'a jeśli by to w czymś pomogło.
pav
Link do diagramu bazy danych


Link do entity Zwierze


Link do entity Zdjecia



Gdzieś na githubie znalazłem, że takie zapytanie może być, trzeba tylko w pliku bazowym dodac if. Tymczasowo mam:

Kod
    {% for zwierze in pagination %}
     {% if loop.index is odd %} {% endif %}
    <div class="row-fluid">
    <ul class="thumbnails">
            {% if loop.index0 is divisibleby(3) and loop.index0 != 0 %}
    </ul>
        </div>
        <div class="row-fluid">
            <ul class="thumbnails">
                    {% endif %}
             {% if zwierze.imie is defined and zwierze.idzwierzatka is defined  and zwierze.imagename is defined%}  
                <li class="span4">
                    <div class="thumbnail">
                        <div class="caption">
                            <h2>{{ zwierze.imie }}</h2>
                            <p><a  href="{{ url('PsySzczegoly', {'idzwierzatka':  zwierze.idzwierzatka }) }}">
                              <img src="{{ asset('zdjecia/zwierzeta/') }}{{ zwierze.imagename }}" class="img-rounded" />
                            </p>
                            <p><a class="btn" href="{{ path('PsySzczegoly', {'idzwierzatka':  zwierze.idzwierzatka }) }}">Zobacz go &raquo;</a></p>
                       </div>
                    </div>
               </li>
             {% endif %}
      {% endfor %}



Jednak po takich warunkach nic sie nie pokaże. Jeśli zmienie z
Kod
and zwierze.imagename
na
Kod
or zwierze.imagename
pokaze się wszystko jako nowy obiekt.

Link do git'a

Z racji iż jest nas 4 w grupie, korzystaliśmy z jednego tutoriala, narobiło się trochę syfu, którego z czasem ogarniemy wink.gif
m44
Cytat(pav @ 31.05.2013, 10:57:53 ) *
Dziękuję za odpowiedź.
Już zmieniłem w controllerze z normalnego sql'owkiego zapytania na buildera:

Kod
          $query = $this->getDoctrine()->getManager()
            ->createQueryBuilder()
            ->select(array('z','w'))  
            ->from('MultimediaAccountBundle:Zdjecia', 'z')
            ->join('MultimediaAccountBundle:Zwierze', 'w')
            ->where('w.kot = 1 ')    
            ->getQuery()
            ->setMaxResults(1)    
            ->getResult();



Może źle napisałem.
Są dwie tabele:
Zwierzeta: idzwierzatka, imie, opis itd.
Zdjecia: idzdjecia, nazwa_pliku, idzwierzatka itd.

Chodzi mi o to, aby wyciągnął z bazy imiona zwierząt i każdemu ze zwierząt dał po 1 zdjęciu jako miniaturkę.

Już dodałem do pierwszego postu.


Spróbuj pogrupować (group by).
pav
@masteron

Jesteś genialny !


Teraz mi tylko wywala błąd po wydłubaniu w entity Zdjecia i dodaniu:

Kod
    /**
     * @ORM\ManyToOne(targetEntity="Zwierze", inversedBy="zdjecia")
     * @ORM\JoinColumn(name="idzwierzatka", referencedColumnName="idzwierzatka")
     */
    protected $zwierze;


w Sonata admin bundle wyskakuje błąd:

Kod
An exception occurred while executing 'INSERT INTO zdjecia (imageName, idzwierzatka, path) VALUES (?, ?, ?)' with params ["51aa679303dfb.jpeg", null, null]:

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'idzwierzatka' cannot be null


Entity jak w przed ostatnim moim poście.
m44
To teraz zobacz sobie w profilerze Symfony ile masz zapytań do bazy. Z każdą iteracją prawdopodobnie tworzy osobne zapytanie.
Nawet jak dasz tam joina, to i tak pobieranie całej kolekcji po to, żeby w pętli (w metodzie dodanej do encji) zwrócić pierwszy element kolekcji to bardzo zły pomysł (dodanie do encji dodatkowej metody również).
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.