Nette\Database MemberAccessException u related

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
matoni555
Člen | 40
+
0
-

Zdravím,
updatoval jsem Nette na poslední verzi 2.0.8 a na stage serveru se mi po několika obnovení stránky objevuje následující chyba na řádku 300 v souboru /Nette/Database/Table/ActiveRow.php:

Nette\MemberAccessException
Cannot read an undeclared column „product_id“.

Po smazání cache databáze stránky běží v pořádku, ale po zobrazení několika stránek se objeví zase tato chyba.

Kód je následující:

{var $mainImages = $product->related('products_images')->where('is_main', 1)}
{if $mainImages->count() > 0}
	{var $mainImage = $mainImages->fetch()}
	...
{/if}

V databázi MySQL mám tabulku products a products_images.
Tabulka products_images má sloupec product_id s cizím klíčem na sloupec id v tabulce products.

Divné je, že na lokále se mi chyba ještě neobjevila. Na lokále mám MySQL 5.5.25a a na stage serveru 5.5.28–1.

Zkoušel jsem do related přidat i druhý parametr, ale ani toto nepomohlo.

{var $mainImages = $product->related('products_images', 'product_id')->where('is_main', 1)}
{if $mainImages->count() > 0}
	{var $mainImage = $mainImages->fetch()}
	...
{/if}

Díky za radu

vvoody
Člen | 910
+
0
-

Celkom by som bol zvedavý na ladenku.

matoni555
Člen | 40
+
0
-

Tady je výstup z laděnky: http://www.matonoha.cz/…2db0132.html

enumag
Člen | 2118
+
0
-

Škoda že to nevisí v dokumentaci jako velký červený nadpis… používat NDB na stable verzi Nette není dobrý nápad a neříkám to zdaleka poprvé. Je to přesně kvůli těmto chybám. Zkus nasadit master z GitHubu, tam by se to stávat už nemělo. Nezapomeň smazat cache.

Pokud chyba nezmizí, bude asi potřeba více informací než jen laděnka.

vvoody
Člen | 910
+
0
-

Nieje tam tento bug už celkom dlho? Ak je to teda ten bug čo myslím, tak ho môžeš obísť tak, že uvedieš parameter do funkcie count:

{if $mainImages->count('*') > 0}
hrach
Člen | 1844
+
0
-
  • count('*') spousti vlastni dotaz, coz v tomto pripade neni urcite mysleno
  • osobne bych to napsal takto, ale myslim, ze to by chybu neresilo
    {var $mainImage = $product->related('products_images', 'product_id')->where('is_main', 1)->fetch()}
    {if $mainImage}
  • myslim, ze v masteru bude ta chyba taky, respektive nevim o oprave, ktera by toto fixovala a nebyla ve stablu.
  • dulezite dotaz
    • chyba nastene po refreshich teze stranky, nebo mezitim prohlizis i jine stranky (tzn. do chache zapisuje i jina stranka)

Ted me tak napada, zkus ten master, mozna by to vlastne pomoci mohlo…

matoni555
Člen | 40
+
0
-

enumag: Proč používat NDB na stable verzi Nette není dobrý nápad?
hrach:

{var $mainImage = $product->related('products_images', 'product_id')->where('is_main', 1)->fetch()}
{if $mainImage}

Tak jsem to měl, jen jsem to zkoušel i přes ten count().

Nasadil jsem master a dělá to stále stejné. Cache samozřejmě mažu.
Smažu cache, prohlížím si stránky a najednou se zobrazí ta chyba. Nemůžu určit žádné určité pořadí, dělá to po náhodném počtu různých stránek.

Uvedený kód mám jinak u výpisu produktů v kategoriích a stejný u detailu produktu. Jen u kategorie je $product z foreach.

hrach
Člen | 1844
+
0
-

hmhm, potreboval bych nejaky workflow jak to nasimulovat. pricina je jasna, vazebni sloupec se v nejakem divnem pripade nedostane do cache. respektive, v poslednim pripade, nez nastane chyba… a otazka je proc, protoze by tam vzdy mel byt…

matoni555
Člen | 40
+
0
-

Ok, jak můžu pomoci?

hrach
Člen | 1844
+
0
-

najit sled stranek po kterym se ti to stane. samozrejme hledej ty, ktery pouzivaji stejny dotaz.
potom potrebuji tu presne predtim…a idealne izolovat rozdily..

matoni555
Člen | 40
+
0
-

Našel jsem sled, po kterym se to vždy stává.

Mám tabulku produktů products, dále tabulku obrázků products_images a tabulku variant produktů products_variants. V tabulce products je sloupec code, který je NULL, pokud má produkt varianty (pak má každá variant svůj code v tabulce products_variants).

Pokud zobrazí stránku s produktem, který nemá varianty, a za ní stránku s produktem, který má varianty, tak to vyhodí tu chybu. Pokud si zobrazím dvě stránky s produktem, kde oba buď mají varianty nebo nemají, tak je vše v pořádku.

V tabulce products_variants je stejně jako u products_images sloupec product_id s cizím klíčem do tabulky products.

saimons
Člen | 293
+
0
-

Na tom sledu asi neco bude, ja jsem se to snazil take vypozorovat na me aplikaci a tohle mi pripada povedome. A i by to vysvetlovalo proc po nekolikatem pokusu, kdy jsem vymazal cache vse fungovalo spravne, protoze byl prihlasenej zrovna uzivatel, ktery nesplnoval tyto podminky a cache se spravne vygenerovala.

matoni555
Člen | 40
+
0
-

Jak to vypadá s opravou té chyby?

hrach
Člen | 1844
+
0
-

tak, ze bych nerad, aby me v utery vyhodily. do te doby fakt ee.

hrach
Člen | 1844
+
0
-

Predpokladam, ze pouzivas ConventionalReflection, je to tak?

matoni555
Člen | 40
+
0
-

Používám výchozí, tzn. DiscoveredReflection. Respektive nikde nic jiného nenastavuji.

hrach
Člen | 1844
+
0
-

Bohuzel se mi nepodarilo zjistit situaci, kdy se to deje, nasimulovat to. Nasel jsem ale jedno slabe misto, ktere by to mohlo zpusobovat, ackoliv mne to v mem testovacim prikladu i presto funguje :)

Zkus v GroupedSelection na readek 168 vlozit toto:

$this->accessColumn($this->column);
matoni555
Člen | 40
+
0
-

S touhle úpravou to funguje!

matoni555
Člen | 40
+
0
-

Díky

saimons
Člen | 293
+
0
-

Behem tohoto tydne prejdu z Nette 2.0.7 na 2.0.8 s timto fixem na ostrem serveru a take to otestuji.

knoxa
Člen | 16
+
0
-

Hoj,
objevila se mi stejná chyba jako autorovi tohoto vlákna v následujícím kódu:

<?php
    private function findIndications(ActiveRow $licenceType)
    {
        foreach($licenceType->related('licence_indication_type') as $indication) {
            dump($indication);
        }
    }
?>

Háže MemberAccessException:
Cannot read an undeclared column „id“ na ActiveRow->related()->offsetGet()->__get()

Schéma:
licence_type – zdroj ActiveRow
licence_indication_type – 1:N vazba, odtud potřebuji data

DB: Postgre 9.2.3
Nette: 2.1-dev (2faed5d)

Napadá vás něco?

hrach
Člen | 1844
+
0
-

jo, pouzij discovered reflection.

knoxa
Člen | 16
+
0
-

Používám. V configu:

database:
	reflection: 'discovered'

a když ve funkci z předchozího postu zavolám

<?php
dump($licenceType->getTable()->getDatabaseReflection());
?>

tak vypíše Nette\Database\Reflection\DiscoveredReflection

enumag
Člen | 2118
+
0
-

@knoxa: Zkus ještě smazat cache Nette.

knoxa
Člen | 16
+
0
-

Zkoušel jsem, několikrát včera a pro jistotu i dnes :-) Beze změny…

enumag
Člen | 2118
+
0
-

Že by nějakej problém s Postgre driverem NDB?

hrach
Člen | 1844
+
0
-

prosim te, zaloz nove vlaknu, dej dump zakladni db a zakladni testcase. diky.

knoxa
Člen | 16
+
0
-

Ok, provedu. Dnes odjíždím, tak to nahodím v pondělí.

BTW, zakladním testcasem myslíš vzorový kód a definovat co by mělo být jeho výsledkem na daným vzorku databáze?