Jak dostat najoinované data z databáze do latte

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

Ahoj, prosím o pomoc.
Chtěl bych se zeptat jak mohu vypsat v latté data z najoinované tabulky

Mám tyto dvě fce v modelu:

public function selectTranslateByRow($row) {
	foreach ($row as $item) {
		$item->related('smenutranslation')->where("language_idlanguage", 1)->fetch();
	}
}
public function select() {
	return $this->centrumConnection->table('smenu');
}
  • Provede se query nad dvěma tabulkama

Presenter:

public function renderDefault()
{
	$smenu = $this->smenu->selectBySuperiror(null);
	$this->smenu->selectTranslateByRow($smenu);
	$this->template->smenu = $smenu;
}

Latte:

{foreach $smenu as $item}
	{$item->type} //toto se vypíše (bere to z tabulky smenu)
	{$item->smenutranslation->name} //Zde už nastává neexistující proměnná
{/foreach}

Nevíte prosím jak to upravit abych mohl vypsat pro každý řádek smenu jeho najoinované data z smenutranslation ??

Mockrát díky za odpověd
Míra

ViPEr*CZ*
Člen | 818
+
0
-

Do latte například:

{foreach $smenu as $item}
    {$item->type} //toto se vypíše (bere to z tabulky smenu)
    {var $rel = $item->related('smenutranslation')->where("language_idlanguage", 1)->fetch()}
    {if $rel}
	    {$rel->name}
    {/if}
{/foreach}
Miri
Člen | 117
+
0
-

Díky a kdybych to chtěl mít v modelu? Asi není nejvhodnější cpát dotazy na databázi do latte.

Oli
Člen | 1215
+
0
-

Nevim jestli ti uplně rozumím, ale přijde mě to takový zmatený a složitý co děláš. Chápu to tak, že máš tabulky smenu a smenutranslation a ty jsou propojeny cizím klíčem. A v tabulce smenu je cizí klíč na tabulku smenutranslation třeba smenutranslation_id. Pak by mělo fungovat něco jako:

// model
public function getSmenu()
{
	$context->table('smenu')->where('smenutranslation.language_id', 1);
}

// presenter
public function renderDefault()
{
	$this->template->smenu = $this->smenuModel->getSmenu();
}
{foreach $smenu as $item}
	{$item->type}
	{$item->smenutranslation->name}
{/foreach}

Nebo chceš něco uplně jinýho a já to nepochopil?

ViPEr*CZ*
Člen | 818
+
0
-

Miri napsal(a):

Díky a kdybych to chtěl mít v modelu? Asi není nejvhodnější cpát dotazy na databázi do latte.

To je myšlenka notORM. Ono ostatně už to Vaše {foreach $smenu as $item} v šabloně teprve zavolá SQL. Tj. až když jsou teprve potřeba data, tak se teprve dotáže do databáze.
Takže až teprve v šabloně máte v podstatě nějakou hodnotu klíče, která se mění jak iterujete nad daty a na základě té hodnoty jste schopen sestavit nový dotaz (přes related), takže to je v pořádku.

Miri
Člen | 117
+
0
-

Oli:
Je to přesně naopak, v tabulce smenutranslation je cizí klíč k smenu.
Jedná se mi o to vybrat všechny příslušné hodnoty z tabulky smenu a k nim přiřadit český překlad z tabulky smenutranslation a předat to nějakým rozumným způsobem do presenteru/šablony.

**ViPEr*CZ***
Jasně chápu že se dotážou až v šabloně, ale při nedokážu si představit že bych tam takovýmhle stylem dával všechny dotazy. Docela by to ztratilo význam MVP a model by nebyl potřeba.

ViPEr*CZ*
Člen | 818
+
0
-

Jak to? Už jenom tímhle $this->template->smenu = $smenu; jste předal nějaký objekt do view. Tak proč nad ním iterujete až v šabloně, když myslíte, že onen objekt („model“) není potřeba?
Asi Vás chápu o co Vám jde. Nechce se mi teď moc přemýšlet, tak jen děsně rychle možná na nakopnutí. Takhle by jste musel mít nějakou třídu, která podle ID bude vrace daný řáde z tabulky smenutranslation. Tj. stačilo by si udělat model pro tabulku smenutranslation s delegovanou metodou get, která bude podle klíče vracet správný řádek. Tím máte modely pro každou tabulku. Podle příkladu chcete z smenutranslation pouze jeden řádek (asi vazba 1:1). Tj. přes get nebo přes related se Vám udělá tak jako tak další SELECT a navíc by jste to měl zapouzdřený v modelu (ne jak jsem to uvedl hned prvně).

Oli
Člen | 1215
+
0
-

Miri napsal(a):

Oli:
Je to přesně naopak, v tabulce smenutranslation je cizí klíč k smenu.

Tak na to existuje taková pěkná konstrukce

public function getSmenu()
{
    $context->table('smenu')->where(':smenutranslation.language_id', 1);
}

Nevím jestli to je uplně přesně takhle (ale snad jo). Kdyžtak se na to podivej do dokumentace…

Miri
Člen | 117
+
0
-

ViPErCZ:
Dobře chápu, díky za rady popřemýšlím nad tím.

Oli
Tady je jeden problém, že se musí přidat ještě select kvuli smenutranslation a nevybírají se vždy jen ty řádky které jsou potřeba. Ale nejspíš to takhle nakonec vyřeším, bude to koukám nejjednodušší řešení.

Oběma díky za pomoc

Oli
Člen | 1215
+
0
-

Ja jsem to nikdy takhle nepotreboval, ale nemas potom nekonzistentní data? Podle mě by měli jít vybrat takhle všechny sloupce, který jsou relevantní k danýmu řádku z smenu.

Me to prijde i lepsi z hlediska vykonu. To tvoje reseni (jestli ho dobre chapu) polozi pro kazdy radek z smenu dalsi dotaz do smenutranslation nebo ne?

ViPEr*CZ*
Člen | 818
+
0
-

Tak samozřejmě co uvádí Oli může být problém a otázka zní, zda-li je dobře návrh databáze. Já se to snažil pojmout v obecném měřítku jak jsi získat related data a nemít „přímý“ dotaz sql v šabloně.
Pokud je to vazba 1:1, pak lze jak naznačil Oli udělat JOIN přes ten where zápis a mít to v jednom dotazu, což v téhle situaci bude asi lepší. Obecně jsi se ptal na related metodu a tam se generuje další dotaz a buď si ušetřit psaní a volat to v šabloně jak jsem ukázal a nebo to řešit například formou extra modelu (což zapouzdří problém do třídy).