Nette Database – Problém s JOIN a ActiveRow
- panPéťa
- Člen | 3
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:
- 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) .
- 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
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)
- Pavel Kravčík
- Člen | 1196
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
Děkuji, zkoušel jsem si to již před tím. WHERE, LIMIT i GROUP 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
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();