databáze místo query použít selection
- lucasso
- Člen | 7
Zdravím,
prosím o radu.
Místo klasického database query
$query = 'SELECT
'.$this->table.'.'.$this->primary_key.',
'.$this->table.'.created_when,
'.$this->table.'.active,
'.$this->table.'.id_login,
'.$this->table_desc.'.id_language,
'.$this->table_desc.'.name,
'.$this->table_desc.'.description
FROM '.$this->table.'
INNER JOIN '.$this->table_desc.' ON
('.$this->table.'.'.$this->primary_key.' = '.$this->table_desc.'.'.$this->primary_key.')
';
$res = $this->database->query($query);
$this->template->posts = $res->fetchAll();
bych rád použil něco v tom smyslu jako $this->database->table(‚news‘)->where(),–>select(),… jenze mi to stale hlasi chyby…
takto vypada trida
<?php
namespace App\Presenters;
use Nette,
App\Model;
/**
* News presenter.
*/
class NewsPresenter extends BasePresenter
{
/** @var Nette\Database\Context */
private $database;
private $table = 'news';
private $table_desc = 'news_desc';
private $primary_key = 'id';
private $primary_key_desc = 'id';
public function __construct(Nette\Database\Connection $database) {
$this->database = $database;
}
public function renderListNews()
{
$query = 'SELECT
'.$this->table.'.'.$this->primary_key.',
'.$this->table.'.created_when,
'.$this->table.'.active,
'.$this->table.'.id_login,
'.$this->table_desc.'.id_language,
'.$this->table_desc.'.name,
'.$this->table_desc.'.description
FROM '.$this->table.'
INNER JOIN '.$this->table_desc.' ON
('.$this->table.'.'.$this->primary_key.' = '.$this->table_desc.'.'.$this->primary_key.')
';
$res = $this->database->query($query);
$this->template->posts = $res->fetchAll();
}
}
nemuze to byt tim Nette\Database\Connection co je v konstruktoru, nebo nejaky use?
Jiz nemam sil, nedokazu se pohnout.
Predem moc dekuji za rady
- David Matějka
- Moderator | 6445
pro pouziti NDBT (tedy table
) musis injectnout
Nette\Database\Context
, nikoliv Connection
- thm
- Člen | 147
U presenterů nemusíš používat konstruktor stačí použít anotaci @inject u public proměnné:
/** @var Nette\Database\Context @inject */
public $context;
Pak už jenom voláš
$this->context->table('news')->where(...)->order(...);
EDIT: opraveno getTable() na table()
Editoval thm (23. 2. 2015 16:35)
- lucasso
- Člen | 7
vim, ze je takto ten dotaz osklivy, to je take jeden z duvodu, proc se ho chci zbavit.
Nette\Database\Context jsem zmenil, diky za tip, ale jeste to neni uplne tak, jak bych potreboval. Z toho hnusnyho dotazu, co jsem napsal rucne, bych to chtel udelat hezky nejak takto:
$this->database
->table('news')
->select('id')
->select('id_login')
->select('created_when')
->select('active')
->where('id',
$this->database
->table('news_desc')
->select('description')
);
nicmene u joinovane tabulky news_desc bych chtel vypsat vsechny sloupce, ale takto to hazi hlasku, ze muze obsahovat pouze 1 sloupec. Respektive delam spatne JOIN?
Nenapada Vas, jak to upravim?
Moc diky
- thm
- Člen | 147
Sorry je to samozřejmě $this->database->table('news')
a
né getTable()
->select() osobně vůbec nepoužívám, nejsem si úplně jistý, ale Nette si samo přijde na to jaké sloupce v tabulce používáš a pak automaticky vyselectuje jenom ty konkrétní, používané.
Spojování tabulek je popsáno hezky v dokumentaci
Editoval thm (23. 2. 2015 16:34)
- David Matějka
- Moderator | 6445
Filozofii NDBT je vybirat data pouze z jedne tabulky, viz hned zacatek v doc:
Nette\Database\Table zjednodušuje a optimalizuje výběr dat z databáze. Hlavní myšlenkou je načítání dat pouze z jedné tabulky a tak, aby se tyto dotazy pokládaly jen jednou.
koukni se na medoty ref a related u active row: https://doc.nette.org/…ase/explorer, ale pokud trvas na vyberu dat jednim dotazem, pouzij join syntaxi, ktera je uvedena u filtrovani, ale necha se aplikovat i pro select
- lucasso
- Člen | 7
děkuji za rady, vyřešil jsem to tak, že v presenteru mám:
$listNews = $this->content->table('news');
$this->template->posts = $listNews;
a do šablony jsem přes related
a foreach
přidal
relační tabulku.
<tr n:foreach="$posts as $post" >
<td>{$post->id_news}</td>
{foreach $post->related('news_desc','news_id')->where('id_language', 1) as $desc}
<td>{$desc->name|truncate:30}</td>
<td>{$desc->description|truncate:90}</td>
{/foreach}
<td>{$post->active}</td>
<td>{$post->created_when|date:'F j, Y'}</td>
<td><a n:href="News:editNews $post->id_news">upravit</a></td>
</tr>
Sice to funguje, ale nevím, jestli se to takto v nette standardně řeší, proto to ještě přikládám na ukázku, jestli nepíšu blbosti.
může to takto být?
děkuji za koment
- thm
- Člen | 147
Ano, takto je to dobře. Teda alespoň podle mě. Ještě je možné
v databázi pospojovat tabulky přes cizí klíče a ušetřit si tak psaní
ještě o název spojovacího sloupce v related, případně využívat
takových zápisů jako je např.
$post->user->name
kde post je ActiveRow,
user je název tabulky (která je propojená přes cizí klíč
s tabulkou posts) a name je název sloupce u toho šťastného uživatele. Je
to zase všechno hezky popsáno v dokumentaci.