Načtení related dat do template

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

Ahoj,
dotaz začátečníka.

Aplikace Tipovačka:
Mám db tabulku ‚match‘, která udržuje sportovní utkání. A tabulku ‚tip‘, která obsahuje ‚match_id‘(FK), ‚tip‘, ‚user_id‘. Tabulka ‚tip‘ obsahuje uživatelské tipy (1,0,2) na sportovní utkání.

Při výpisu všech utkání si načtu všechna utkání, načtu tipy z další tabulky a předám do template.

$matches = $this->database->table('match');
foreach ($matches as $match) {
			$tip = $match->related('tip')->where('user_id', $this->user->id)->fetchField('tip');
}

$this->template->matches = $matches;

Moje otázka je. Jak se na ten ‚related‘ tip dostanu v latte template?
Předpokládal jsem něco jako match->tip ale to mi nejede.

{foreach $matches as $match}
	{$match->id}  // tohle jde
	{$match->tip} // tohle vyhodí chybu
{/foreach}
GEpic
Člen | 566
+
+1
-

speedees napsal(a):

Ahoj,
dotaz začátečníka.

Aplikace Tipovačka:
Mám db tabulku ‚match‘, která udržuje sportovní utkání. A tabulku ‚tip‘, která obsahuje ‚match_id‘(FK), ‚tip‘, ‚user_id‘. Tabulka ‚tip‘ obsahuje uživatelské tipy (1,0,2) na sportovní utkání.

Při výpisu všech utkání si načtu všechna utkání, načtu tipy z další tabulky a předám do template.

$matches = $this->database->table('match');
foreach ($matches as $match) {
			$tip = $match->related('tip')->where('user_id', $this->user->id)->fetchField('tip');
}

$this->template->matches = $matches;

Moje otázka je. Jak se na ten ‚related‘ tip dostanu v latte template?
Předpokládal jsem něco jako match->tip ale to mi nejede.

{foreach $matches as $match}
	{$match->id}  // tohle jde
	{$match->tip} // tohle vyhodí chybu
{/foreach}

Takto by to mělo a taky funguje. $match->tip by ti měl vypsat primární klíč tabulky. $match->tip->sloupec by ti měl vypsat libovolný sloupec z tabulky tip odpovídajícího záznamu match.

Pokud chceš využívat relace, je to otázka nastavení MySQL. Musíš používat InnoDB Engine a relace si navrhnout např. přes phpMyAdmin pomocí cizích klíčů.

speedees
Člen | 8
+
0
-

GEpic napsal(a):
Takto by to mělo a taky funguje. $match->tip by ti měl vypsat primární klíč tabulky. $match->tip->sloupec by ti měl vypsat libovolný sloupec z tabulky tip odpovídajícího záznamu match.

Pokud chceš využívat relace, je to otázka nastavení MySQL. Musíš používat InnoDB Engine a relace si navrhnout např. přes phpMyAdmin pomocí cizích klíčů.

Díky za odpověď.

Bohužel zmíněné mi vyhazuje:

Nette\MemberAccessException
Cannot read an undeclared column 'tip'

InnoDB a cizí klíče si myslím, že mám navrženy správně. Protože když si proměnou ‚tip‘ v presenteru nechám vypsat:

foreach ($matches as $match) {
          $tip = $match->related('tip')->where('user_id', $this->user->id)->fetchField('tip');
		  \Tracy\Debugger::barDump($tip) ;
}

Vidím v dumpu přesně ty hodnoty, které vidět chci :) Vyjímka vyskakuje až v template.

blaztar
Člen | 93
+
+1
-

Do šablony si předáváš pouze $matches. Takže ten foreach z related použij až tam.

MW
Člen | 626
+
+1
-

No podle mě $tip to do šablony nepředáváš.
Zkus si v šabloně dumpnout $matches.

speedees
Člen | 8
+
0
-

Jo, máte oba pravdu.
$tip jsem si do šablony nepředával.

Jak jej ale teda správně předat, tak aby bylo možné zavolat v šabloně {$match->tip}?

iguana007
Člen | 970
+
-1
-
foreach ($matches as $match) {
          $match->tip = $match->related('tip')->where('user_id', $this->user->id)->fetchField('tip');
}
David Matějka
Moderator | 6445
+
+1
-

@iguana007 to nepujde, ActiveRow je readonly
https://forum.nette.org/…ed-read-only

CZechBoY
Člen | 3608
+
+2
-

Já teď celkem často posílám do šablony pole, kde mám dodatečný informace k entitě (místo related nebo protože potřebuju related->related).

$this->template->matches = $matches = $this->model->getMatches();
$this->template->tips = $this->model->getTips($matches->fetchPairs(null, 'id_match'));
{foreach $matches as $match}
	{if isset($tips[$match->id_match])}
		{$tips[$match->id_match]->tip} {* nebo co chceš vypsat ... *}
	{else}
		-
	{/if}
{/foreach}

Nevim jak moc správný to je přístup, ale nic jiného mě zatim nenapadlo…

MW
Člen | 626
+
0
-

Jde nám o toto nebo se pletu?

speedees
Člen | 8
+
0
-

MW napsal(a):

Jde nám o toto nebo se pletu?

Ano, o to nám jde, díky.
Ale i tam nevidim předávání té related proměnné $book do template. Takže si nemyslím, že by pak v template $author->book fungovalo. Nebo se pletu?

MW
Člen | 626
+
0
-

Pokud toto mas v template a tak to funguje

foreach ($author->related('book.author_id') as $book) {
    echo $book->title;
}

To co psal @DavidMatějka se týká případu, kdy potřebuješ upravit data, tobě jde jen o výpis.

Editoval MW (26. 2. 2016 10:29)

CZechBoY
Člen | 3608
+
0
-

Btw nemůžeš v modelu prostě udělat ->select navíc? S tím, že by sis musel určit co vše chceš selectnout.

Něco takovýho:

function getMatches ($userID)
{
	return $this->database->table('match')
		->select('match.*')
		->select(':tip.tip userTip')
		->where(':tip.user_id = ? OR :tip.user_id IS NULL', $userID);
}
{foreach $matches as $match}
	{if $match->userTip}
		Máte vsazeno: {$match->userTip}
	{else}
		<a n:href="vsadit, match => $match->id">Vsadit na zápas</a>
	{/if}
{/foreach}
speedees
Člen | 8
+
0
-

Díky všem za názory.
Nakonec používám metodu related() v template.

Tímto to mužem uzavřít.