Vícenásobná práce s Nette Database
- Radimorous
- Člen | 30
Mám situaci:
Model
public function getObsah($id)
{
return $this->database->query('SELECT * FROM obsah WHERE id = ?', $id);
}
presenter
public function renderDefault($id)
{
$this->template->obsah = $this->model->getObsah($id);
}
template
<meta name="description" content="{foreach $obsah as $o}{$o->description}{/foreach}">
<meta name="keywords" content="{foreach $obsah as $o}{$o->keywords}{/foreach}">
Problém je, že v template se vypíše pouze první řádek správně (description), od druhého řádku už to vrací prázdné hodnoty. Dalo by se to řešit jedním {foreach} pro celou šablonu nebo vytvořením více funkcí v modelu, ale to asi není ideální. Dají se nějak převést hodnoty z databáze na pole a vypisovat je takhle v template? Nebo jakým způsobem je lepší tento příklad řešit?
- Zdeno1981
- Člen | 115
Ahoj,
model si uprav takto:
public function getObsah()
{
return $this->database->query('SELECT * FROM obsah')->fetchPairs($key, $value);
}
presenter:
public function renderDefault()
{
$this->template->obsah = $this->model->getObsah();
}
template:
<meta name="description" content="{$obsah['value']}">
Editoval Zdeno1981 (28. 12. 2011 21:17)
- Radimorous
- Člen | 30
Tohle mi však nevyřeší to, že chci mít jednu funkci v modelu a jedno volání v presenteru pro výpis všech hodnot v templatu… Podle Tvého příkladu bych pouze dostal hodnotu description bez nutnosti volat při výpisu {foreach}, jak jsem psal nahoře. Co jsem to teď googlil, tak bych spíš potřeboval něco jako jsem našel, že v dibi je fetchAssoc(‚id‘); , to ale v Nette\Database není.
- Radimorous
- Člen | 30
uestla napsal(a):
Zkusil bych v presenteru
$this->template->obsah = $this->model->getObsah($id)->fetchPairs('id');
Zkusil jsem, výsledek je
SQLSTATE[HY000]: General error: PDO::FETCH_KEY_PAIR fetch mode requires the result set to contain extactly 2 columns.
- uestla
- Backer | 799
To bude tím, že voláš přímo query(...)
, které vrací
PDOStatement
, ve kterém snad při více než 2 řádcích ve
výsledku nastává tahle chyba. Nejúčinnějším řešením bych viděl
použít fetchPairs
u Selection, čili v Modelu upravit následovně:
function getObsah($id)
{
return $this->database->table('obsah')->find($id);
}
A v presenteru nechat upraveno na
$this->template->obsah = $this->model->getObsah($id)->fetchPairs('id');
- Radimorous
- Člen | 30
Tak se mi to povedlo následovně:
presenter:
$this->template->id = $id;
$this->template->description = $this->model->getObsah($id)->fetchPairs('id', 'description');
$this->template->keywords = $this->model->getObsah($id)->fetchPairs('id', 'keywords');
$this->template->title = $this->model->getObsah($id)->fetchPairs('id', 'title');
.....
sablona:
<meta name="description" content="{$description[$id]}">
<meta name="keywords" content="{$keywords[$id]}">
.....
Sice to není úplně tak, že bych v presenteru volal getObsah($id) jen jednou, ale to by fetchPairs() musela umět párovat více sloupců najednou. Takže jsem vyhrál napůl – aspoň nemusím mít v modelu pro každý volání speciální funkci. Díky za radu!
Editoval Radimorous (29. 12. 2011 1:48)
- uestla
- Backer | 799
Jáj, tak to jsem špatně pochopil strukturu z tvého prvního příspěvku :-D
Na načtení řádku je metoda $row->fetch()
:-)
// Model
return $this->database->table('obsah')->find($id);
// Presenter
$this->template->obsah = $this->model->getObsah($id)->fetch();
// template
<meta name="description" content="{$obsah->description}">
<meta name="keywords" content="{$obsah->keywords}">
- Radimorous
- Člen | 30
uestla: Spíš jsem to v prvním příspěvku nejasně popsal. Každopádně teď už mi to funguje jak má, super a díky moc!!