Proč Nette\Database hleda nazev tabulky ciziho klice z nazvu sloupce
- joseff
- Člen | 233
Zdravím. Dejme tomu že existuje tabulka article kde je id, title a author_id (to je pochopitelne cizi klic na authora). Jenze tabulku author nelze vytvorit (nechme stranou proc). Vytvorime tedy tabulku article_author kde bude id a name. Nakonec samozrejme nastavim v tabulce article cizi klic author_id na tabulku article_author.
Ted pouziji \Nette\Database a ziskam jeden radek article:
$database->table('article')->where('id',1)
Vse je OK, ale kdyz chci zjistit jmeno autora vyhodi mi to chybu:
echo $database->author->name;
Base table or view not found: 1146 Table 'testdb.author' doesn't exist
Zrejme je to proto, ze \Nette\Database se snazi z nazvu sloubce (tedy author_id) odvodit nazev tabulky (tedy author). Ale proc se radeji nezepta databaze ci je to cizi klic a na tu tabulku pak odkaze to nechapu. Poradi nekdo? (samozrejme bych mohl zmenit nazev sloubce na article_author_id a vse by fungovalo, ale to my neprijde idealni a navic se snazim prijit na to proc to tak Nette\Database dela)
- Richard Faila
- Člen | 40
Řeším podobný problém. Mám tabulku akce, kde jsou sloupce vytvoril a organizuje. Protože oba ukazují na záznam jiný řádek ve stejné tabulce users nemohou se oba jmenovat users_id.
Existuje nějaký způsob jak donutit Nette, aby pro přístup do tabulky z users použila hodnoty z těchto sloupců? Něco jako through ale pro ref?
Ještě dodám, že řešení používající cizí klíče by mi nepomohlo, protože na hostingu mám jen MyISAM.
PS: tohle není poprvé co jsem na tento problém narazil.
- Jan Voráček
- Člen | 90
A proč pro tyhle případy, jako zmiňují joseff a Richard Faila, nepoužít vlastní Reflection? Případně by se dalo nouzově použít i NotORM_Structure_Discovery nebo se pletu?
Editoval Jan Voráček (30. 8. 2011 20:58)
- Richard Faila
- Člen | 40
přepisovat Reflection sice asi jde, ale je to takové těžkopádné. NotORM_Structure_Discovery by bylo o mnoho lepší, ale Nette\Database to pokud vím zatím neumí.
- jh
- Člen | 22
Taky to teď řeším.
Napadlo mě přidat pár řadků kódu do __get metody u ActiveRow classy.
Něco jako „když bude v názvu podtržítko, tak použij jako název tabulky
první část“.
Pak bych si v tabulkách, kde mám víc cizích klíčů do stejné tabulky,
pojmenovával ty sloupce např.
user_first_id, user_second_id
<?php
$connection->table('articles')->get(1)->user_first->name;
?>
Jako sloupec s cizím klíčem by to mělo identifikovat user_first_id a
jako table pak user.
Otázkou je, kde všude jinde bych to musel změnit.
//Což mi teď došlo, že bych pak nemohl mít tabulky, kde je ve jménu podtržítko, takže by se vzalo vše //kromě té poslední části.
Editoval jh (11. 9. 2011 18:48)
- David Grudl
- Nette Core | 8228
Discovery už je součástí frameworku, stačí ji nastavit
přes $connection->setDatabaseReflection()
- hrach
- Člen | 1838
- v aktuální nette bohužel ani v s DiscoveryReflection
neuděláš
$database->table('article')->get(1)->author->name;
- aby to fungovalo (s jakoukoliv reflection), musíš nyní použít
$database->table('article')->get(1)->article_author->name;
- problém je totiž v tom, že aktuální DiscoveryReflection (a to i ta v NOTORM) nejsou tak uplně discovery, oni totiž vazební sloupec generují konvencí! nette database notorm
Na řadu nyní přichází hrachův PULL:
- s ConventionalReflection:
$database->table('article')->get(1)->ref('article_author', 'author_id')->name;
- s DiscoveredReflection:
$database->table('article')->get(1)->author->name;
Můj poslední pull opravuje plno chyb a právě i kompletně přepracovává reflekce, které byly dosti děsivé. Sorry, ale fakt jsem vždy přemýšlel, jestli použív getReferencingTable, nebo getReferencedTable, atp.
Editoval hrach (21. 12. 2011 10:27)
- czita
- Člen | 5
Zkoušel jsem na vzorové databázi. Tabulka book má cizí klíče authorID a maintainerID.
<?php
$book = $this->context->database->table("book")->get(1);
echo $book->author->name;
echo $book->maintainer->name;
?>
Ukázkový kód padne na výjimce Trying to get property of non-object. Kvůli čemu se používá ve třídě DiscoveredReflection funkce strtolower? Tipuju, že tam bude zakopaný pes. Z authorID se pak stává authorid a z maintainerID maintainerid. Bez strtolower mi to funguje.