vícenásobný related – problém
- ajda2
- Člen | 66
Narazil jsem na chybu(možná na mé straně) při použití funkce
related().
Při vykonání kódu
{foreach $galleries as $gallery}
<div id="tabs-{$gallery->id}">
<ul id="sortable1" class="connectedSortable gallerySortable ui-helper-reset">
{foreach $gallery->related('image') as $image}
{var $lang = $image->related('image_lang_data', 'image_id')->where("language_id = ?", 1)->fetch()}
<li id="{$image->id}" class="ui-state-default">
<img src="{$basePath}/images/small/{$image->id}.jpg" alt="{$lang->title}">
</li>
{/foreach}
</ul>
</div>
{/foreach}
Nette Database provede dotazy
SELECT `id`
FROM `gallery`
SELECT *
FROM `gallery_lang`
WHERE (`gallery_lang`.`gallery_id` IN (1, 2))
SELECT *
SELECT *
FROM `image`
WHERE (`image`.`gallery_id` IN (1, 2))
FROM `image_lang_data`
WHERE (`image_lang_data`.`image_id` IN (1, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25)) AND (`language_id` = 1)
SELECT *
FROM `image_lang_data`
WHERE (`image_lang_data`.`image_id` IN (NULL)) AND (`language_id` = ?)
Což skončí samozřejmě chybou.
Zde je schéma databáze
https://www.dropbox.com/…b_schema.png
a zde dump, pro jistotu i s daty
https://www.dropbox.com/…/db_dump.sql
Editoval ajda2 (30. 7. 2012 18:34)
- vvoody
- Člen | 910
Aky presne error ti to hadze? Skusil som si to a u mna je notiska: Trying to get property of non-object v sablone na {$lang->title}. To je celkom jasne, len sa nenasiel zaznam v db, preto fetch vratilo NULL namiesto ActiveRow. Ale divnejsie je preco nette u teba nevykona ziadny dotaz nad gallery. Predsa v premennej $galleries mas vyber z tabulky gallery?
- ajda2
- Člen | 66
@vvoody: První dotaz jsem neuváděl, nepřišel mi důležitý –
doplnil jsem.
Hodí mi to naprosto stejnou hlášku jako Tobě. Problém je ale v tom, že
ten obrázek v DB je.
Nette ho jej dokonce načte
FROM `image_lang_data`
WHERE (`image_lang_data`.`image_id` IN (1, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25)) AND (`language_id` = 1)
Jenomže ho načte špatně(brzy) – je to ten s ID 25. Má gallery_id =
2
a poté v druhém cyklu, kdy se prochází galerie, by se mělo vzít z DB
image kde je gallery_id = 2, ale provede se toto
SELECT *
FROM `image_lang_data`
WHERE (`image_lang_data`.`image_id` IN (NULL)) AND (`language_id` = ?)
A v tom je podle mě ten problém. Místo NULL by tam mělo být
25. Řešilo se to zde https://forum.nette.org/…ette-2-1-dev
ale byl sem požádán o vytvoření nového vlákna
- vvoody
- Člen | 910
Aha tamto, tak to je dost neprijemny bug :) vsimol som si ze related ma treti parameter $forceNewInstance, ktory mozno nastavit na TRUE, cim sa to viacnasobne zanorenie „zredukuje“ ale zase sa znasobi pocet dotazov na db co urcite nechceme.
{foreach $gallery->related('image',null,true) as $image}
A co takto do sablony si poslat vyber obrazkov zoradenych podla gallery id
$gals = $this->context->database->table('gallery');
$imgs = $this->context->database->table('image')->where('gallery_id',$gals->select('id'))->order('gallery_id');
$this->template->imgs = $imgs;
a v sablone to uz treba len nejako rozumne odsledovat kedy sa pri prechadzani obrazkami zmeni galeria, toto je trosku humus :D
{? $gal = 0}
{foreach $imgs as $img}
{if $img['gallery_id'] != $gal}
{if $gal != 0}
</ul>
</div>
{/if}
<div>
<ul id="sortable1" class="connectedSortable gallerySortable ui-helper-reset">
{$img['gallery_id']}
{? $gal = $img['gallery_id']}
{/if}
{var $lang = $img->related('image_lang_data', 'image_id')->where("language_id = ?", 1)->fetch()}
<li id="{$img->id}" class="ui-state-default">
<img src="{$basePath}/images/small/{$img->id}.jpg" alt="{$lang->title}">
</li>
{last}
</ul>
</div>
{/last}
{/foreach}
ale panel mi nakoniec ukazuje len 3 query :) nad kazdou tabulkou jednu. Samozrejme len ako docasne riesenie, ta sablona vyzera otrasne.
- ajda2
- Člen | 66
@hrach, @vvoody:
Právě jsem pro jistotu vyzkoušel stáhnout Nette 2.0.4 a poté jsem zkusil
https://github.com/…-refactoring
a se stejným výsledkem.
Pomohlo jen přidat forceNewInstance.
Cache samozřejmě pokaždé mažu.
Nemůže být problém ještě někde jinde? Nastavení DB, PHP, Nette?
Poskytnu klidně zdrojáky, či cokoliv co bude potřeba. Chtěl bych to
vyřešit.
Tady je laděnka s chybou. https://www.dropbox.com/…base_bug.htm Je tam dumplá
proměnná $lang. V posledním řádku, kde by měl být ActiveRow z tabulky
„image_lang_data“ s „image_id“ = 25 je FALSE. Což bude podle mě
způsobeno posledním dotazem do DB
SELECT *
FROM `image_lang_data`
WHERE (`image_lang_data`.`image_id` IN (NULL)) AND (`language_id` = ?)
Editoval ajda2 (1. 8. 2012 9:30)
- hrach
- Člen | 1838
Tak jeste jednou, $forceNewInstance
nema
vyznam, protoze uz nikdy nebude, pac se to delat ted vzdy :P Hosi, fakt nevim co
s tim, prosim, spuste si doma ty testy: https://forum.nette.org/…ette-2-1-dev#…
a rekneme te mi, jestli vsechny projdou.
Editoval hrach (2. 8. 2012 20:32)
- ajda2
- Člen | 66
@hrach: Tak jsem spustil testy. Přikládám jejich výsledek https://www.dropbox.com/…exm/test.log
S testy nemám žádnou zkušenost, takže pokud je chyba ještě na mé
straně, prosím dejte mi vědět.
Chápu, že $forceNewInstance je slepá ulička, ale zatím pro mne jediné
funkční řešení.
Každopádně je dost divné, že někomu to funguje a někomu ne. Jiné
nastavení Mysql, PHP?
- ajda2
- Člen | 66
Nedalo mi to a vyzkoušel sem založit kompletně nový projekt. Použil jsem
f-db-dev od Hracha. Vytvořil sem novou databázi a naplnil ji dumpem, co tady
přikládám. Použil sem ho schválně, protože někdo psal, že mu to
funguje. Jenže stejně to nefunguje. Jsem už opravdu bezradný.
Přikládám PHP info, jestli třeba není zakopaný pes tam. https://www.dropbox.com/…fo%28%29.htm
- ajda2
- Člen | 66
Tak konečně se problém VYŘEŠIL!
Problém byl tam, kde bych ho vůbec nečekal. Při stažení
f-database-refactoring Nette od hracha jsem dal možnost stáhnout v zipu
přímo z Gitu. Z nějakého důvodu to nestáhlo poslední commit. Problém
vyřešila synchronizace repository. Takže v f-database-refactoring to opravdu
funguje, jen je si třeba ohlídat staženou verzi. Poté stačí přehodit
pořadí parametrů v konstruktorech a v továrničkách, aby to
korespondovalo s „ofic.“ Nette.
@hrach: Co tě přimnělo k prohození parametrů v konstruktorech tříd Selection, GroupedSelection a ActiveRow? Jinak moc děkuji za ochotu!