Proč Nette\Database hleda nazev tabulky ciziho klice z nazvu sloupce

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

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)

David Grudl
Nette Core | 8228
+
0
-

Tohle zatím není implementované.

Richard Faila
Člen | 40
+
0
-

Ř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.

VaKvas
Začátečník | 111
+
0
-

David Grudl napsal(a):

Tohle zatím není implementované.

Davide prosim, jak by toto melo vypadat v budoucnu? Nemas nejaky casovy horizont a naznak, jak to pujde resit?

Jsem ted ve fazi, kdy kvuli tomuto budu muset prepsat velkou cast aplikace..

Diky !

Filip Procházka
Moderator | 4668
+
0
-

@**VaKvas**: http://www.notorm.com/

Jan Voráček
Člen | 90
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

Discovery už je součástí frameworku, stačí ji nastavit přes $connection->setDatabaseReflection()

hrach
Člen | 1838
+
0
-
  • 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)

hrach
Člen | 1838
+
0
-

Nechal jsem se zmás komentářem, a špatně jsem napsal výše příklad. Opraveno do snad funkční podoby.

czita
Člen | 5
+
0
-

Bude přepracovaná DiscoveredReflection fungovat s camel case pojmenovanými tabulkami a klíči?

hrach
Člen | 1838
+
0
-

Hm! To by mohlo, vyzkoušej :)

czita
Člen | 5
+
0
-

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.

hrach
Člen | 1838
+
0
-

hm, řekl bych, že chyba bude v tom, že to strtolower se nepoužívá jinde, ne, že by se mělo vyhodit :) díky, to bude chtít opravit.

czita
Člen | 5
+
0
-

hrach napsal(a):

hm, řekl bych, že chyba bude v tom, že to strtolower se nepoužívá jinde, ne, že by se mělo vyhodit :)

Tomu úplně nerozumím. Kde by se měla strtolower ještě používat?

ViPEr*CZ*
Člen | 817
+
0
-

Už se toto nějak vyřešilo? Ve funkci getBelongsToReference nám to stále vrací $column a $key jako lowercase.