Vypsání počtu komentářů u novinky

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

Ahoj,

mám na webu novinky, jsou vypsány všechny pod sebou. U každé z nich bych chtěl mít napsaný počet komentářů, které k dané novince existují. Mám model Novinky.php:

class Novinky extends BaseModel
{

	private $table = 'webnews';

	public function findAll()
	{
		return $this->db->select('*')->from($this->table);
	}
}

Dále mám model Komentare.php:

class Komentare extends BaseModel
{

	private $table = 'webcomments';

	public function count($id)
	{
		return $this->db->select('count(*)')->from($this->table)->where('id_news=%i', $id);
	}

}

Ten obsahuje metodu count, která vrátí počet komentářů novinky podle id.

Presenter se jmenuje NovinkyPresenter.php a vypadá následovně:

class NovinkyPresenter extends BasePresenter
{

	/********************* view default *********************/

	public function renderDefault()
	{
		$novinka = new Novinky;
		$this->template->novinky = $novinka->findAll()->orderBy('date')->fetchAll();
	}
}

A nakonec šablona:

{foreach $novinky as $novinka}
<h2>{$novinka->title}</h2>
<p class='text'>{$novinka->text}</p>
<p class='komentare'>Komentáře []</p>
{/foreach}

Do hranatých závorek bych chtěl vypsat počet komentářů, jenomže nevím, jak dál.. Nevím, jak to prostě zkloubit dohromady. Děkuji moc za rady.

Panda
Člen | 569
+
0
-

Je možné si do šablony předat i model komentářů a pak si u každé novinky zavolat příslušnou metodu, ale to není moc efektivní. Lepší bude si přidat do modelu novinek metodu, která provede dotaz s JOINem:

<?php
private $commentsTable = 'webcomments';

public function findAllWithCommentsCount()
{
	return $this->db->select('%n.*, COUNT(%n)', $this->table,
			$this->commentsTable . '.id_news')
		->from($this->table)
		->leftJoin($this->commentsTable)
		->on('%n = %n', $this->table . '.id', $this->commentsTable . '.id_news');
}
?>

Nebo si na to můžeš udělat view a provést jednoduchý SELECT na něj.

weckho
Člen | 94
+
0
-

Díky, ještě jsem k dotazu doplnil:

->groupBy($this->commentsTable . '.id_news');

Bez toho dotaz vracel chybu (Mixed columns, nebo tak). Nyní to funguje, jenom teď nevím, ve které proměnné v šabloně mám ten počet uloženej.. Text té novinky mám například v {$novinka->text}, a ten počet v {$novinka->???} ? :)
Nebo jak k němu přistoupit?

Díky moc!

Panda
Člen | 569
+
0
-

weckho napsal(a):

Díky, ještě jsem k dotazu doplnil:

->groupBy($this->commentsTable . '.id_news');

Bez toho dotaz vracel chybu (Mixed columns, nebo tak). Nyní to funguje, jenom teď nevím, ve které proměnné v šabloně mám ten počet uloženej.. Text té novinky mám například v {$novinka->text}, a ten počet v {$novinka->???} ? :)
Nebo jak k němu přistoupit?

Díky moc!

Aha, já zapomněl na AS…

return $this->db->select('%n.*, COUNT(%n) AS `commentsCount`', $this->table,

A bude to v $novinka->commentsCount.

weckho
Člen | 94
+
0
-

Super, díky moc, funguje.

Ještě jsem chtěl poprosit o jednu radu. Mezi údaji o té novince vytahuji z databáze také datum přidání novinky. Nevím ale moc, kde (na jakém místě v kódu) mohu datum upravit do správného formátu? Dělá se to nějak v presentru? Popřípadě jakým způsobem? Nebo až v té šabloně? Mám to datum jako unix time, normálně v int sloupci.

Díky moc!

jasir
Člen | 746
+
0
-

Ještě jsem chtěl poprosit o jednu radu. Mezi údaji o té novince vytahuji z databáze také datum přidání novinky. Nevím ale moc, kde (na jakém místě v kódu) mohu datum upravit do správného formátu? Dělá se to nějak v presentru? Popřípadě jakým způsobem? Nebo až v té šabloně? Mám to datum jako unix time, normálně v int sloupci.

Jasně, klidně až v šabloně. {$mojedatum |date:"Y-m-d"}

weckho
Člen | 94
+
0
-

Díky moc, narazil jsem na další problém. Mám u formuláře vytvořené políčko:

$form->addHidden('id_news');

V šabloně ho potom vykresluji:

{!$form['id_news']->control}

Jak ho naplním hodnotou? Potřebuji mu předat ID novinky, ke které bude komentář patřit. ID mám v šabloně v {$novinka->id}, nebo v samotné URL.

Děkuji za pomoc.

jasir
Člen | 746
+
0
-

weckho napsal(a):

Díky moc, narazil jsem na další problém. Mám u formuláře vytvořené políčko:

$form->addHidden('id_news');

V šabloně ho potom vykresluji:

{!$form['id_news']->control}

Jak ho naplním hodnotou? Potřebuji mu předat ID novinky, ke které bude komentář patřit. ID mám v šabloně v {$novinka->id}, nebo v samotné URL.

Myslím, že by to mělo jít:

{?$form['id_news']->setValue($novinka->id)}

…ale myslím, že by jsi to neměl dělat a promyslet, jak tuto hodnotu nastavit již při vytváření formuláře v presenteru.

weckho
Člen | 94
+
0
-

Chápu, hotovo, díky. Řeším další problém:

Uživatel píšící komentář si může ke jménu přidat adresu webu. Potřebuji adresu očistit od „http://“ (pokud to adresa obsahuje), protože to k adrese přidávám napevno v šabloně při výpisu komentářů (tak aby to tam pak nebylo dvakrát). Dělám to proto, že ne každý to do adresy napíše a potom by mi některé odkazy nefungovaly.

Chci se zeptat, jestli uvažuji správně, nebo bych to měl řešit jinak? Dále potom, pokud je postup správný, budu vstup z formuláře před vložením do DB upravovat v metodě, která formulář zpracovává (v mém případě „commentFormSubmitted“), nebo jinde?

Děkuji.

Ondřej Brejla
Člen | 746
+
0
-

Data z formu bych předal metodě v modelu, která si data upraví jak potřebuje a případně uloží do db.

PetrP
Člen | 587
+
0
-

Jen ještě k tématu přidání hodnoty do hidden. Když nepoužiju tovarničku ale vytvořím Hidden ručně, tak můžu použít první parametr v HiddenField::__construct forcedValue, které když nastavím nejde na stránce přepsat (např javascriptem)

$form['id_news'] = new HiddenField($this->template->novinka->id);
David Grudl
Nette Core | 8228
+
0
-

Hidden políčka by se měly plnit jako jakékoliv jiné políčka, tj. metodou setDefaults()

PetrP
Člen | 587
+
0
-

Ale forcedValue je tak pěknééééé ;]

Ted vážně: proč je forcedValue špatně? Řeší to právě předávání id a podobně, u kterých je záhodno aby se nedali na cestě změnit.