selection / activeRow – related()
- qteck
- Člen | 164
ještě jednou zdravim :-),
https://api.nette.org/…lection.html – třída selection
return $this->fetchAll()->select('id, title, text')->where('id',1);
- selection pro výběr více než jednoho řádku, takže se hodí třeba pro výpis kategorií, nebo sekcí atp.
protected function getTable()
{
preg_match('#(\w+)Repository$#', get_class($this), $m);
return $this->connection->table(lcfirst($m[1]));
}
public function findAll()
{
return $this->getTable();
}
https://api.nette.org/…tiveRow.html
return $this->related()->select('id, title, text')->where('id',1);
pro specifický výběr.
pokud tento specifický výběr použiji vyhazuje mi to error "Nette\MemberAccessException
Call to undefined method Todo\ArticleRepository::related()" – nedefinovaná metoda..
prvně jsem si říkal, že bych i měl vytvořit abstrakci jako u Selection metod a dědit třídu ActiveRow, ovšem když jsem si všiml, že abstrakce Repository dědí od Nette\Object říkám si, že nette object musí obsahovat aji metodu related.
ovšem asi tomu tak není vzhledem k chybě, kterou to vyhazuje, nebo dělám něco špatně?
Díky za reakce.
- enumag
- Člen | 2118
Děláš to špatně. Metoda related je na ActiveRow. Ten ActiveRow je nějaký konkrétní záznam z databáze (řekněme článek) a k tomuto konkrétnímu záznamu hledáš něco souvisejícího, čeho je ale více (řekněme komentáře). Repository není jeden záznam, ale tabulka, tam tedy nemáš co volat nějaké related. Nejdříve si pomocí get vytáhni ten záznam a na něm pak volej related. Anebo si vytáhni nějaké selection (klidně findAll) a tu metodu related volej až při procházení toho selection pomocí foreach – Nette to samo zoptimalizuje na co nejmenší počet dotazů.
- qteck
- Člen | 164
ahaha, tak to jsem related blbě pochopil, možná by se spíš hodilo spíše ref() taktéž od activeRow, problém je že mi to tu metodu nemůže najít.
potřeboval bych právě vybrat vyloženě jeden článek, bez souvislostí, jediné co mam je id.
tak si říkám, nebylo by možné třeba $this->ref()->select(‚id, title, text‘)->where(‚id‘,1); ?
každopdáně u každé z těch metod mi to píše že ji nemůže najít, bo to hledá v Todo\ArticleRepository::ref() což by nemusela být blbost, vzhledem k tomu že article repository dědí repository a ten dědí nette\object.
co myslíš?
- enumag
- Člen | 2118
Na to nepotřebuješ ani ref ani related, stačí místo ref() dát findAll() a nakonec přidat limit(1)->fetch() a mělo by to fungovat.
Navíc ale nepotřebuješ ani to, stačí ti find/get/… podle toho jaké metody má tvé repository. Ty metody select, where, limit i fetch jsou v tomto případě zbytečné.
Editoval enumag (15. 11. 2012 14:04)
- qteck
- Člen | 164
na to co potřebuji tedy stačí v podstatě
public function findBy(array $by)
{
return $this->getTable()->where($by);
}
-- volat $this->findBy(array('id'=>'1'));
a ekvivalentním zápisem by bylo:
public function findByFind($by)
{
return $this->getTable()->find($by);
}
když mam tedy teď jeden záznam a vrátím se k threadu ve kterým jsi mi pověděl že se sql dotaz spustí až při foreachu jak tento jeden dotaz vypíši, když foreach není potřeba?
presenter vypadá takto:
class ArticlePresenter extends Nette\Application\UI\Presenter
{
private $articleRepository;
public function inject(Todo\ArticleRepository $articleRepository)
{
$this->articleRepository = $articleRepository;
}
public function renderDefault()
{
$this->template->article = $this->articleRepository->ff();
}
}
- qteck
- Člen | 164
nééé :-D, to jsme se špatně pochopili. jde teď o šablonu.
{block content}
<h1 style="">Lorem Ipsum forem popuk</h1>
{foreach $article as $row}
{$row->title}
{$row->text}
{/foreach}
jde o výpis článku a vzhledem k tomu že v article je v podstatě jenom jeden řádek, není foreach potřeba.
Jakto tedy vypsat bez použití toho foreachu.
v presenteru to mám zapsané takto:
public function renderDefault()
{
$this->template->article = $this->articleRepository->ff();
tedy v šabloně bych to očekával pod $article->title; atp.. ale není to tam, je tam zase soubor objektů různých atd..
- enumag
- Člen | 2118
Selection představuje množinu řádků, aby to bylo možné, implementuje rozhraní Iterator, je to tedy iterátor nad řádky (díky tomu funguje foreach). SQL dotaz se provádí když z toho selection buď taháš první řádek (fetch) anebo jej začínáš procházet (rewind).
Když potřebuješ jen jeden řádek, stejně se vytvoří selection, akorát už z něj dostaneš jen ten první řádek.