DI vs jednoduchost přístupu k DB
- TrubiT
- Člen | 10
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
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
- @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ů.
- Metoda startup je protected a není důvod měnit její viditelnost na public.
- TrubiT
- Člen | 10
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
@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
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)