Nette Database – Problém s JOIN a ActiveRow

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

Databáze je v MySQL. Zde jsou tabulky Article, kde jsou důležité sloupce id a datum a Article_about kde jsou pouze 3 sloupce – id, article_id a about.

Sloupec about je naplněn písmeny A, B, D, Z a P.

Mé SQL, které funguje v phpMyAdmin je:

SELECT *
FROM article
LEFT JOIN article_about
    ON article_about.article_id = article.id
	WHERE article_about.about = 'A'
	GROUP by article.id
	ORDER by article.datum DESC

Ve verzi pro nette jsem prohodil Article a Article_about.

$this->template->article = $this->database->table('article_about')
			->select('*',$this->database->table('article'))
			->where('about = "A"')
			->group('article_id')
			->order('datum DESC')
			->limit(7);

Zde jsou 2 chyby:

  1. nefunguje ORDER ani LIMIT, datum, které je v tabulce Article, se jakoby přeskočí a pokud to zadám jako article.datum tak to vyhodí chybu (No reference found for $article_about->article) .
  2. což je pro mne dosti podstatnější chyba je to, že při výběru z DB a vypisování hodnot vyskočí „Object of class Nette\Database\Table\ActiveRow could not be converted to int

V proměnných v Tracy se mi ukáže:

array (8)
	1 => Nette\Database\Table\ActiveRow #4d67
		table private => Nette\Database\Table\Selection #2e9f
		data private => array (7)
			id => 1
			title => "titulek" (37)
			content => "nějaký text" (174)
			text => "delší text" (1696)
			datum => Nette\Utils\DateTime #b3d9
				date => "2012-09-11 00:00:00" (19)
				timezone_type => 3
				timezone => "Europe/Prague" (13)
			author => 0
			picture => ""
		dataRefreshed private => FALSE
	2-8 řádek, viz ten 1.
Pavel Kravčík
Člen | 1196
+
+1
-

Udělej nejdřív první dotaz. Potom si na něj volej ref/related podle potřeby. Musíš mít primární sloupec v tabulce article, jinak se Ti to nebude párovat.

$data = $this->database->table('article_about')->where(group etc.)->fetchAll();

foreach($data as $articleAbout)
{
	echo $articleAbout->ref('article','article_id')->id;
}

https://doc.nette.org/…ase/explorer

Editoval kzk_cz (9. 1. 2015 12:22)

panPéťa
Člen | 3
+
0
-

Super, děkuji moc! Zní to pěkně, ale pokud to chápu dobře, zbytek už je teda na mě → musím si udělat vlastní order i limit, je tomu tak?

Editoval panPéťa (9. 1. 2015 13:04)

Pavel Kravčík
Člen | 1196
+
0
-

Promiň byl jsem líný. Podmínky použij na ten první dotaz jak je ->where().

Má to fluent zápis, takže z tvého příkladu třeba takhle. Ref budeš volat až na ty vytříděné, kdy k nim potřebuješ přiřadit ten konkrétní článek.

$data = $this->database->table('article_about')
	->where('about','A')
	->group('article_id')
 	->order('datum DESC')
	->limit(7)
	->fetchAll();
panPéťa
Člen | 3
+
0
-

Děkuji, zkoušel jsem si to již před tím. WHERE, LIMITGROUP se mi vyřešily, ale bohužel ORDER ne, protože ten sloupec je v article a ne v každém z article_about. Asi si to hodím zpátky do jednoho pole a v něm to seřadím – další problém, nejde to řadit dle id, protože mohou být nějaké zpáteční články (i když jich bude minimum) a řadit to v poli dle data je také hloupost, protože tím omezením (LIMIT) bych už rovnou mohl vyřadit nějaké aktuální..

Editoval panPéťa (9. 1. 2015 13:30)

Pavel Kravčík
Člen | 1196
+
0
-

Jasně už to dává větší smysl. Pokud přepisuje projekt do Nette, můžeš předělat i strukturu do něčeho rozumnějšího (myslím strukturu).

Jinak můžeš použít to related() a to by mělo vracet Selection a to se dá ještě třídit. Podívej se do článku na ActiveRow a Selection. :)

	$articleAbout->related()->order();