Nette\MemberAccessException po použití related
- Izzy
- Člen | 5
Zdravím lidičky,
mám problém s Nette\Database, konkrétně s použitím metody related.
Používám verzi Nette 2.0.10 stabilní, uvolněnou 6. 3. 2013 (tzn.
v tuto chvíli aktuální stable verzi).
Tato věc se zde na fóru již řešila, nicméně např. zde
bylo řešením přejití na novější verzi Nette, což u mě bohužel nejde
(nicméně 2.1-dev jsem nezkoušel).
Chyba se vyskytuje víceméně náhodně, například po pokusu o vyhledání produktů v katalogu. Kód pro výcuc z databáze je následující:
<?php
public function getProduktMainObrazek($id)
{
return $this->getProdukt($id)->related('produkt_obrazek')->where(array('typ' => 0))->fetch();
}
?>
Vrácený ActiveRow pak přidám k seznamu produktů takto:
<?php
foreach ($produktList as $prod)
{
$prod['obrazek'] = $this->produktModel->getProduktMainObrazek($prod['id_produkt']);
}
?>
A už jen pošlu do šablony na vykreslení.
Databáze vypadá takto:
Tabulka produkt
obsahující PK id_produkt
.
Tabulka produkt_obrazek
obsahující FK
id_produkt
.
Používám DiscoveredReflection.
Po jednom či více refreshi (F5) chyba zmizí a produkty se normálně načtou.
Očekávám, že je to chyba způsobená nějakým konfliktem pri cachování DB, nicméně vypnout cache samozřejmě není úplně košer řešení.
Budu rád za každou radu co s tím.
Díky :)
- hrach
- Člen | 1838
Cele to pouzivas spatne, ke kazdemu prvku z $produktList vybiras obrazek – tedy slozitost O(n). Pouzij nette database tak jak mas, tedy na itemu z $produktList volej related, a bude slozitost O(1). Vice se dozvis v me prezentaci a videu:
- Izzy
- Člen | 5
Díky za odpověď :)
Nevím jestli jsem se předtím vyjádřil dost srozumitelně. Jde mi o to, že
data k produktu mám v tabulce produkt
, a obrázky k tomu
produktu mám v tabulce produkt_obrazek
, kde se na produkt
odkazuji pomocí FK id_produkt
. K jednomu produktu existuje více
obrázků, kde jeden (obrázek s vlastností typ = 0
) je hlavní
obrázek – a tento záznam odpovídající hlavnímu obrázku si já chci
vytáhnout a přidat k výběru dat o produktu. Takže ve výsledku budu mít
Selection obsahující několik produktů, každý produkt s vlastnostmi jako
nazev
, cena
, barva
a navíc ještě bude
mít vlastnost obrazek
, dodanou pomocí related. Svůj kód jsem
trošku upravil tak, aby odpovídal tomu co je v prezentaci (mimochodem,
prezentace nefunguje korektně v Chromu – po 5. slajdu se nepohne dál).
Takže teď to vypadá následovně:
Výběr seznamu produktů z databáze (v modelu)
<?php
public function getProduktList($paginator = NULL)
{
$produktList = $this->getTable()->order('id_produkt DESC');
if(isset($paginator)) {
$produktList->limit($paginator->getLength(), $paginator->getOffset());
}
return $produktList;
}
?>
Přiřazení obrázků (v presenteru)
<?php
foreach ($produktList as $produkt) {
foreach ($produkt->related('produkt_obrazek') as $produkt_obrazek) {
if($produkt_obrazek->typ == 0) {
$produkt->obrazek = $produkt_obrazek;
}
}
}
?>
Předpokládám, že zde by to mělo jít řešit i pomocí
$produkt->related('produkt_obrazek')->where(array('typ' => 0))
,
nicméně teď pro zkoušení to mám tak.
Možná Vám přijde divné, že tam ten obrázek přidávám tak divně, ale je to kvůli tomu, že nejprve vyberu jen ten seznam produktů s kterým pak manipuluji (nějaké where atd.) a až potom k těm produktům které v seznamu zbudou přidávám ty obrázky a pošlu seznam do šablony. (Kdybych tam obrázek připojoval rovnou v modelu tak mi ho z tama ty použití where zase vyhodí)
Takže tak jak to je teď by to mělo být správně? Chyba stále
přetrvává.
Zjistil jsem, že ji „ručně“ vyvolám vždy když smažu cache, refreshnu
stránku (načte se v pořádku), refreshnu znova a nastane
MemberAccessException. Jinak se objevuje asi víceméně náhodně.