DI vs jednoduchost přístupu k DB

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

Zdravím všechny, po delší době jsem zpět u nette a změnilo se toho hodně. Řeším dilema, jak zvolit pro mě nejlepší řešení mého problému.

public function startup()
{
	// záznam pomocí USER ID ze session
	$this->dbUser = $this->db->table('users')->find($this->user->getId())->fetch();
}

public function renderDefault()
{
	// jednoduchá návaznost 1:N
	$this->template->balance = $this->dbUser->related('wallets')->sum('balance') + 0;
	// návaznost 1:1
	$this->template->sponsor = $this->dbUser->sponsor->username;
	// sum 1:N:N
	$this->template->commission = $this->dbUser->related("commissions")->getReferencedTable('transactions', 'transaction_id')->where("type", 'commission')->where('status', 'ok')->sum('amount') + 0;
}

Takhle si vytáhnu co potřebuju na pár řádcích a musím uznat – ta syntaxe se mi fakt líbí! Nelíbí se mi ale, že dotazy do DB jsou v prezenteru, chtěl bych to nějak oddělit do jiné třídy (Repository) a používat pomocí DI. Můžu si vytvořit Repository jak je v dokumentaci v některých příkladech a předávat všem metodám neustále UserID a filtrovat výsledky podle toho. Podstatou je, že stávající dotazy všechny základají na záznamu jednoho uživatele a z něj se dopídí svázaných záznamů v jiných tabulkách a proto je to tak jednoduché. Proto se ptám …

Je možné takto přistupovat k záznamům i v modelech nebo je nějaký jiný vzor jak to řešit? Předem děkuji!

Editoval TrubiT (17. 4. 2013 23:16)

David Matějka
Moderator | 6445
+
0
-

nejjednodussi a lepsi nez v presenteru bude to presunout do nejakeho modelu, treba takhle:

class UserModel extends \Nette\Object
{

	protected $connection;

	public function __construct(\Nette\Database\Connection $connection)
	{
		$this->connection = $connection;
	}

	public function getUser($id)
	{
		return $this->connection->table('users')->find($id)->fetch();
	}

	public function getBalance(\Nette\Database\Table\ActiveRow $user)
	{
		return $user->related('wallets')->sum('balance') + 0;
	}
	....
}

//presenter
public function injectModels(UserModel $userModel)
{
	$this->userModel = $userModel;
}

public function startup()
{
	$this->dbUser = $this->userModel->getUser($this->getUser()->getId());
}

public function renderDefault()
{
	$this->template->balance = $this->userModel->getBalance($this->dbUser);

	....
}
Majkl578
Moderator | 1364
+
0
-
  1. @matej21: Konstrukce „presunout do nejakeho modelu“ je poměrně úsměvná. Aplikace má pouze jeden model, i ze samotného názvu a charakteristiky MVC/MVP to vyplývá. Metoda „injectModels“ a pojmenování „UserModel“ tedy nedává smysl, jelikož indikuje více modelů.
  2. Metoda startup je protected a není důvod měnit její viditelnost na public.
Glottis
Člen | 129
+
0
-

no a vsichni mame vzdycky jeden presenter kdyz to tak vyplyva z nazvu?

Editoval Glottis (18. 4. 2013 8:06)

TrubiT
Člen | 10
+
0
-

matej21 napsal(a):

	public function getBalance(\Nette\Database\Table\ActiveRow $user)
	{
		return $user->related('wallets')->sum('balance') + 0;
	}

Právě mě se nelíbí, že bych měl metodám, jako je třeba tato, předávat ActiveRow. Ale to už se dá asi pořešit :)
Kdyby měl někdo ještě návrhy tak šup sem s ním! Díky

Editoval TrubiT (18. 4. 2013 9:22)

hAssassin
Člen | 293
+
0
-

@TrubIt > a proc se ti to nelibi? ActiveRow v tomto pripade zastupu entitu a co jinyho bys tam chtel predat nez prave konkretni entitu, ktery se to tyka? Je teda fakt, ze pokud by to byla plnohodnotna entita tak by mela primo metodu getBalance v sobe a sama si ji pocitala (zjistovala). Ale to uz je jiny problem.

@Majkl578 > a jak by jsi to pojemoval? Obcas pouzivam nazev promennych napr $testRepos pokud pracuju primo s repozitarem. Pokud mam ovsem jeste mezivrstu nejakych fasad nebo services tak uz nevim jak to pojmenovat. Ani jedno ($testFacade/$testService) se mi nelibi jako nazev promenny ($testFacade by jeste slo, $testService je dost matouci). Napadlo me akorat $testDomain protoze se vlasne jedna o domenu ale pak si nedovedu predstavit domenu na domenou → $domainDomain :-) Co ty na to?

Editoval hAssassin (18. 4. 2013 9:55)

TrubiT
Člen | 10
+
0
-

hAssassin napsal(a):

@TrubIt > … Je teda fakt, ze pokud by to byla plnohodnotna entita tak by mela primo metodu getBalance v sobe a sama si ji pocitala (zjistovala). Ale to uz je jiny problem.

Rozepiš se o tomdle víc prosím tě, ty osobně bys to udělal pomocí Entit nebo bys předával pořád ActiveRow (getBalance je jen jedna z moře metod)? Zajímá mě jak by vypadal návrh pomocí těch Entit, jak se na to dá napojit DI a takové ;)

Editoval TrubiT (18. 4. 2013 10:01)

llook
Člen | 407
+
0
-

Zkus se mrknout na YetORM, mohlo by to řešit tvůj problém a není to takový overkill jako Doctrine.

hAssassin
Člen | 293
+
0
-

Ano, taky doporucu YetORM, pripadne si vystacis i s Nette\Database ala quickstart. Pokud by te to ale zajimalo, tak zacni asi zde a pak taky na planete.

TrubiT
Člen | 10
+
0
-

Díky, na to YetORM se ještě mrknu.