Repository dotazy, jak na chytre dotazovani

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

Ahoj, chtel jsem se zeptat jestli lze nejak docilit toho, aby bylo dotazovani treba ArticleRepository efektivni. Pokud bych chtel hledat aktivni clanky uzivatele tak bych si napsal neco jako findAllActiveOfUser(), tim si ale pro kazdy status musim napsat vlastni metodu.
Ptam se tedy, zdali jde docilit neceho jako:

$ArticleRepository->findAll->status(ArrticleRepository::STATUS_ACTIVE)->byUser($id);

Nevim pod cim to mam hledat. Mohl by nekdo uvest priklad?
Dekuji =)

Editoval johnymachine (30. 1. 2014 11:53)

xciza
Člen | 194
+
0
-

Já bych si do db udělal ještě jeden sloupec právě s oním statusem a pak by si vyhledával jenom v tomhle sloupci. Dle mě nejjednodušší řešení ;)

Tomáš Kolinger
Člen | 136
+
0
-

Teoreticky ano ale nevidím v tom velký přínos…

Proč ne jednoduše ->findAllBySatatusAndUser(ArticleRepository::STATUS_ACTIVE, $userId)? Skládat podmínku v presenteru/šabloně je mi proti srsti, chápu model jako oddělenou část aplikace a v tomhle případě by to až tak oddělené nebylo.

Každopádně pokud dotazy chceš skládat, tak je jednodušší použít DibiFluent či Nette\Database\Table\Selection či Doctrine\ORM\QueryBuilder. Než psát vlastní API a v tomhle případě by to bylo i dost složité.

Majkl578
Moderator | 1364
+
0
-

Zajímavý náhled na tenhle problém má i Benjamin Eberlei v článečku, kde popisuje použití Criteria a Specification patternu.

Oli
Člen | 1215
+
0
-

Nevidím žádný přínos oproti tomu co psal @Tomáš Kolinger. Ale pokud by jsi to chtěl tak jak píšeš, tak to jde relativně jednoduše…

Repository
{
	cont STATUS_ACTIVE = 'active';
	protected $query;

	public function status($status)
	{
		$this->query = $this->query->where('status = ?', $status);
		return $this->query; // vrací selection kvůli fluent
	}
}

ArticleRepository extends Repository
{

	public function findAll()
	{
		return $this->connection->table('article');
	}

	public function byUser($id)
	{
		$this->query = $this->query->where('user_id = ?', $id);
		return $this->query; // vrací selection kvůli fluent
	}
}
johnymachine
Člen | 12
+
0
-

No nechel jsem to proto, ze pri pridavani treba data pridani se musi resit situace kdy chci vyhledavat s datem, ale ne se statusem a tak podobne.

Chci docilit retezeni pomoci Nette\Database\Table\Selection. V podstate je to takove ->where(‚neco‘, $hodnota)->where(‚neco‘, $hodnota) s pred definovanymi „neco“.

Potreboval bych asi nejaky priklad… =)

Oli
Člen | 1215
+
0
-

Ten můj příklad ti nestačí?

johnymachine
Člen | 12
+
0
-

Oli napsal(a):

Ten můj příklad ti nestačí?

Pardon post bez F5 =)
Dekuji to je asi ono =)

johnymachine
Člen | 12
+
0
-

Dobra tak jsem to implementoval. Predpokladam metodu status v ArticleRepository. Mam vsak jeden dotaz, jakou ma pocatecni hodnotu $query. Samozrejme to ted zpusobuje Call error non function… =)

Editoval johnymachine (30. 1. 2014 14:16)

Oli
Člen | 1215
+
0
-

Jaj, mas pravdu zapomněl jsem ji nastavit v tom fetchAll. Tam to connection… (nechce se mě to na mobilu cely vypisovat ;)) Se rovna Query, který se i vrátí.

ten status je v repository, protože ArticleRepository dedi z Repositroy a ta metoda teda bude ve všech třídách přístupná a nemusíš ji psát porad.

johnymachine
Člen | 12
+
0
-

Mohl by jsi to prosim jeste rozvest? Takto to jiste nefunguje, mozna mi neco zrejmeho unika. Ale v query je (object typu) selection, a ten jiz nema metody meho repository… (zretezit takto nelze)
Predpokladam syntax retezeni jako jsem psal vyse. =)

Editoval johnymachine (30. 1. 2014 16:32)

Oli
Člen | 1215
+
0
-

Ajo, mas pravdu. To jsem si jaksi neuvědomil. Tak pak to musíš udělat tak, že všechny metody budou vracet $this a příkaz pak bud nebude vypadat tak pěkně

// execute už nevrací $this, ale instanci selection
$ArticleRepository->findAll->status(ArrticleRepository::STATUS_ACTIVE)->byUser($id)->execute();

nebo po byUser() už nebudeš moct nic přidat a metoda byUser() bude vracet selection. Respektive budes moct pridat metody, ktere jsou třídy selection (where, order, limit, …)

Mesiah
Člen | 240
+
0
-

Majkl578 napsal(a):

Zajímavý náhled na tenhle problém má i Benjamin Eberlei v článečku, kde popisuje použití Criteria a Specification patternu.

Trochu OT, ale funguje Vám ten link? Bohužel je mi vrácena prázdná stránka; můžete mi poradit, jak bych ji mohl získat z Google archivu?

Edit: Link na archiv

Editoval Mesiah (30. 1. 2014 18:18)

Majkl578
Moderator | 1364
+
0
-

Mesiah napsal(a):

Majkl578 napsal(a):

Zajímavý náhled na tenhle problém má i Benjamin Eberlei v článečku, kde popisuje použití Criteria a Specification patternu.

Trochu OT, ale funguje Vám ten link? Bohužel je mi vrácena prázdná stránka

Zkus párkrát obnovit, trochu to zlobí a někdy to vrátí bílou smrt. :)

johnymachine
Člen | 12
+
0
-

Pokud bude vracet $this nebudu moct na konci pouzivat napriklad count(). Premyslel jsem nad tim, jestli repository extends selection? Jak to tedy spravne udelat? Je tu spousta textovych korekci a clovek se pomalu ztraci… =)