Jak pracovat správně s modelem

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

Ahoj,

on je to spíš obecný problém, než s nette…

Ve všech příkladech jsou v metodách modelu sql dotazy, kdy jsou přímo napojené na jména tabulek. Vzhledem k tomu že u projektů (který si dovedu tak nějak rozumně představit v mozkovně) budu mít asi co tabulka to jedna třída. No a když těch tříd bude víc, přijde mi ideální nějak „pořešit“ názvy těch tabulek.

Jenže nevím jak to pořádně udělat – když dám ke každý třídě

/*TableModel.php */
public $table = 'tabulka'

/* base model */
  public function getTable(){
        return $this->table;
    }

bude to sice jednodušší, ale jenom do doby, než se pokusím v nějaký konkrtétní metodě zjistit jména pěti tabulek – to bude zas už docela opruz…

Jak to řešíte? Našel jsem dost diskuzí, ale nikde nějaké doporučení → dělej to tak tak :)

Ve finále jsem se pak pročetl až k doctrine, což mi přijde zas už zbytečně složitý..

díky

westrem
Člen | 398
+
0
-

Trosku spravim reklamu Honzovi Tichemu s jeho 5 vrstvovym modelom, ktory som si vcelku oblubil:
http://www.phpguru.cz/…rstev-modelu

Obecne ja mam teda udelanu vcelku peknu hierarchiu tried podla Honzovho principu, kde vo finalnej faze mam nieco ako PDatabaseModel, ktory ma presne ako pises vynutenu cez interface funkciu getTable a podla toho sa riadi.

než se pokusím v nějaký konkrtétní metodě zjistit jména pěti tabulek – to bude zas už docela opruz

Asi len nechapem otazke ale skus uviest nejaky priklad, kde tvoja predstava koliduje s „vyuzitelnostou“ resp co ti nie je jasne.

colek
Člen | 59
+
0
-

Hmm to vypadá tak nějak jako to, co jsem hledal :) Jen bych se zeptal, jestli nevíš o nějaké větší ukázce jak to funguje. Tak nějak tuším že vytvořím hroznej bastl, musím se ještě víc učit :)

Nilp
Člen | 65
+
0
-

Třeba tendle 4dílný seriál: http://blog.fedecarg.com/…chitectures/

arron
Člen | 464
+
0
-

Ono jako napsat si to sam bude nejspis super cviceni (kterym jsem v omezene mire taky prosel), ale v zasade kdyz vezmes Doctrine2, tak uz nic psat nemusis:-) V nekterych pripadech je to asi kanon na vrabce, ale do budoucna urcite cenne vedomosti a osobne mi ta prace s tim prijde prima:-)

westrem
Člen | 398
+
0
-

arron napsal

Nie je Doctrine2 este pod neustalym vyvojom? Ja osobne by som teda radsej pockal kym to bude mat aku taku ucelenu podobu a potom podla toho studoval

arron
Člen | 464
+
0
-

westrem napsal(a):

Pravda, jeste se porad vyviji, ale nerekl bych, ze se ta rozhrani budou nejak dramaticky menit. Myslim, ze stadium BETA 4 odpovida terminu „aku taku ucelenu podobu“ celkem dobre ;-)

srigi
Nette Blogger | 558
+
0
-

Doctrine 2 je uz IMO pouzitelne na projekty, ktore startuju o 3–4 mesiace do ostrej prevadzky. A samozrejme na devel. Trufam si tvrdit, ze devel firma @medio okolo Jana Ticheho a Onreja Mirtesa uz bezi na Doctrine 2 naostro. Osobne by som sa vobec nebal ho pouzivat.

colek
Člen | 59
+
0
-

Díky za postřehy, ten seriál si určitě přečtu. Na doctrine se určitě podívám, ale aktuálně se musím naučit základnější věci :)

Jinak v rámci hledání jsem našel zajímavý DAO generátor – pro pochopení co tam má všechno být je to fajn.

Šaman
Člen | 2635
+
0
-

Jj, Honzův 5ti vrstvý model je dobrá teorie, máš tam všechno. A můžeš si ho ořezat, já používám tak 3.5 vrstvy a jsem spokojenej.

Od nejabstraktnější:

  • servisní vrstva (většinou statické fce jedné třídy, která zastřešuje celý model – její metody se volají z presenteru)
<?php
// vrati vsechny novinky (nepristupuje do databaze, pouziva nizsi metody modelu)
$news = Blog::getNews();
?>
  • práce s kolekcemi (obsahuje statické metody na nalezení skupin objektů, vrací je jako kolekci která je schopná s nimi dále pracovat. Kolekci mám jako potomka ArrayObject, takže se dá procházet pomocí foreach)
<?php
// najde vsechny komentare od jednoho uzivatele a vrati je jako ArrayObject objektu Comment (pristupuje do db pomoci Dibi a pro kazdy nalezeny zaznam vytvori objekt Comment ktery vlozi do kolekce)
$comments = Comments::getCommentsByUser($userId);
// seradi komentare v kolekci podle data vytvoreni
$comments->sortByDate();
?>
  • práce s jednotlivými entitami v systému (nemusí ale platit že jedna entita je jedna tabulka. Třída může spravovat více tabulek, např. hlavní tabulku a pomocné číselníky které se k ní vážou, nebo také jednu entitu ve více tabulkách – článek v návrhu, schválený, vymazaný ale v archivu) Obsahuje CRUD metody pro danou entitu, do db přistupuje přes Dibi
<?php
// najde komentář podle Id a vytvoří jeho instanci
$comment = Comment::getById($commentId);
// upraví komentář a zase ho uloží
$comment->setLabel('novy titulek')->save();
?>
  • a konečně ta půl vrstva – Dibi. Neodstiňuje nás sice od databáze jako typu úložiště, ale odstiňuje nás od konkrétní SQL syntaxe a tady i od konkrétní Db.

Tohle rozvržení se mi osvědčilo, do db se přistupuje na poměrně jasně určených místech, dá se v modelu udržet pořádek. Není to přímo implementace onoho 5tivrstvého modelu, ale už si tomu dovolím říkat model. Neumožňuje sice výměnu zápisu do Db za třeba zápis do souboru, ale to většina začátečníků nepotřebuje, proto má s vrstvami mapper a repository problém. Až je budu potřebovat, bude čas zase se trochu posunout k vyšším cílům, zatím jsem rád, že už nebastlím SQL dotazy do presenteru. :))


P.S. Sorry, jestli ses ptal na něco trochu jiného. Úplně jsem tvůj dotaz nepochopil, ale rozhodně už v začátku úvah nad modelem zavrhni myšlenku jedna entita = jedna tabulka. Občas to platí, ale stačí abys potřeboval např. vracet ve výpisu uživatele místo idRole její název z jiné tabulky a už ti to přestává platit.

srigi
Nette Blogger | 558
+
0
-

Velmi by ma zaujimal nazor ostatnych na staticke metody Service vrstvy. Casto vidim, ze niekto to nemoze vystat, druhy zase naopak neznasa zbytocne instantovanie objektu. Vas nazor aj nejakymi argumentami…

Patrik Votoček
Člen | 2221
+
0
-

Jelikož používám Doctrine 2 tak jsem si tak nějak zviknul na to to že se instancuje. Nicméně udělal jsem si v BaseEntitě aliasy a metody repository pro danou entitu volám staticky nad danou entitou. Tj. místo $this->em->getRepository('App\Models\FooEntity')->find(1); píšu \App\Models\FooEntity::find(1) mnohdy spíše Models\FooEntity::find(1). (Vypadá to jako AR a je to pohodlné. Navíc jsou to doopravdy jenom aliasy bez další logiky)