Vícenásobná práce s Nette Database

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

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
+
0
-

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
+
0
-

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í.

uestla
Backer | 799
+
0
-

Zkusil bych v presenteru

$this->template->obsah = $this->model->getObsah($id)->fetchPairs('id');
Radimorous
Člen | 30
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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!!