doctrine 2 – sandbox a jak dál

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

Ahoj, začínám se poohlížet po doctrine2 – čerpám hlavně z:
https://forum.nette.org/…-nette-2-0-x
https://forum.nette.org/…-containerem
Prošel jsem si i oba sandboxy od HosipLana i Patrika Votočka…stále ale nevím jak začít. Je toho zkrátka nějak moc najednou (podobně jako když jsem začínal s Nette :)

Oba sandboxy krásně naběhly, ale co dál? Opravdu nevím jak začít – kam co napsat.
Hrozně by mi pomohla ukázka, kde bude nějaký sandbox rozšířený alespoň o jednu tabulku, entitu apod., kde se do šablony předá třeba jedna řádka z databáze.
Poslalo by mě to správným směrem, abych nedělal nějaký prasárny, kterých bych se nedejbože nějaký měsíc držel a pak to přepisoval.

Nemáte odkaz na nějaký takový sandbox nebo jinou ukázku? (článek, diskusi?) Všechny články co jsem zatím viděl skončily u vytvoření funkčního prostředí Nette + Doctrine2 a právě ten první (resp. další) krůček tam chybí.

Díky.

Aurielle
Člen | 1281
+
0
-

Můžeš se inspirovat HosipLanovým DAO – http://www.aceblog.cz/…-dava-smysl/. Nebo prostě zkusit v presenteru něco jako:

public function renderDefault()
{
	// způsob přístupu k EM si upravíš podle toho, jaký sandbox použiješ...
	$this->template->data = $this->context->doctrine->entityManager->getRepository('User')->findBy(array('active' => TRUE));

	// nebo - DQL - vykopírováno z jednoho projektu
	$query = $this->context->doctrine->entityManager->createQuery('SELECT e, r, a FROM AvalonProject\Entities\FairyTail\Episode e
		LEFT JOIN e.subtitles r LEFT JOIN e.arc a ORDER BY e.isOva ASC, e.aired DESC');
	$this->template->episodes = $query->getResult();
}
<ul n:inner-foreach="$data as $user">
	<li>{$user->name}</li>
</ul>

Entity si ukládej kam chceš, hlavně je Doctrine musí najít. Já je mám třeba v %appDir%/entities…

Filip111
Člen | 244
+
0
-

Dokumentaci samotnou jsem zatím jen prolítnul, pročítal jsem seriál na zdrojáku.cz.
Osobně mi samotná dokumentace zatím moc nedá – je tam jen spousta nových pojmů, které se mi jen pletou dohromady.
Až když si to sám vyzkoušim, začne se to v hlavě třídit a dokážu si pod slovem entity mapper a spoustou dalších pojmů představit něco konkrétního. Pak je čas pročíst dokumentaci pořádně :)

Něco mi sandbox už dělá…brzy se zase vrátím s nějakým „obrovským“ problémem.

awsickness
Člen | 98
+
0
-

co se tyce doctrine je tam celkovy problem jak to co nejlepe resit. co clovek to vlastni pristup.
osobne se rozhoduji jakou cestou pujdu.
jestli bude „dataobject“ ten zabalim do repository aby se nemichaly data a funcionalita nad nima.
dalsi pohled je
mit entitu a ta by mela umet sama nad sebou pracovat ?

nejvic se mi libi myslenka mit entitu na ni volat vse
$entity->callSomeQuery();
a uvnitr by mohla byt jakakoliv implementace napriklad i ta hospilanova.

jediny problem je ze jsem nenasel misto kde dane entity podstrcit entityManager :/

Filip111
Člen | 244
+
0
-

Podobný otázky si se snažim taky zodpovědět – jen zatim nemam konkrétní představu jak to dělat lze a jak bych to mohl dělat já.
Resp. zatím jsem se definitivně nerozhodl doctrine použít – mám toho už dost napsanýho pomocí dibi ale pořád to neni tak úplně ono.

Filip Procházka
Moderator | 4668
+
0
-

Já bych ti doporučil si přečíst tyto výživné diskuze

https://forum.nette.org/…-orm-pro-php#…
https://forum.nette.org/…ny-na-notorm

Jenom bych doporučil ignorovat ty doporučení ohledně vnořených containerů, to se ukázalo jako anti-pattern ;)

Editoval HosipLan (11. 1. 2012 17:01)

mkoubik
Člen | 728
+
0
-

awsickness napsal(a):
dalsi pohled je mit entitu a ta by mela umet sama nad sebou pracovat ?

To potom není ORM, ale Active Record ($entity->save() etc.), kterej IMHO porušuje SRP a pokud nepoužíváš jazyk, kterej se na tohle hodí (ruby, smalltalk), tak se lehce dostaneš do problémů (třeba při testování).

awsickness
Člen | 98
+
0
-

mkoubik: to ja vim taky pisu ze by se mi to sice nejvic libilo ale jen takove logicke uceleni.
ted to delam jinak a chystam se to udelat uplne jinak :) ale co je nakonec best practise to asi nikdo nerekne.

Filip111
Člen | 244
+
0
-

@HosipLan: obě diskuse už jsem v minulosti četl…a teď zase. Výsledek je, že z toho mam akorát depku :)
Mj. jsi tam kritizoval mít různý model pro administraci a různý pro frontend, což používám.
V modelu pro frontend jsou klasické metody jako getOne, getAll apod., které vytahují téměř připravená data z DB view.
V administraci mám basemodel s metodami insert, update, delete apod. které automaticky podle struktury tabulky generují sql dotazy. Zjišťuji tam struktury tabulek v DB a případně rozložím data z formuláře do více tabulek (typicky hlavička a jazykově závislá data) apod.

Hlavní je, že se v té admin části občas začínám ztrácet, často to musím stejně přepsat pro konkrétní model a občas je to WTF.
Tohle je něco, kde si slibuju od doctrine výrazné usnadnění díky mapování a propojení entit. Naprostá většina dat se skládá z tabulky pro hlavičku a z tabulky pro jazykově závislé texty, kde může být k jedné hlavičce více záznamů pro různé jazyky.

Otázka 1:
Pokud chápu asociace, tak samotná entita Zbozi bude napojená na další entity podobně jako jsou spojené přes foreign keys v DB? Výsledkem tedy bude hromada navzájem propojených entit (v kterých se po čase člověk taky ztratí).

Chci se zeptat na tvoření entit – konkrétně pro zboží. Informace o zboží jsou rozprsklé asi ve 20ti tabulkách – základní informace, parametry, varianty, obrázky, přílohy, historie cen apod., většina vícejazyčně.

Otázka 2:
Lze Zbozi (tedy dvě základní tabulky – hlavičku a texty) definovat jako jednu entitu nebo musím jako dvě Zbozi a ZboziText ? Pracovat budu vždy se zbožím jako jedním objektem a při uložení budu chtít aby se to do těchto tabulek „samo“ rozdělilo…na jaké by to mělo být úrovni? Repository nebo ještě výš?

Díky.

Filip Procházka
Moderator | 4668
+
0
-

@**Filip111**: Pokud chceš začít dělat s ORM, musíš přestat uvažovat v tabulkách a začít uvažovat v objektech. Dává smysl, aby tahle entita měla vazbu na tuhle entitu a tohle se předávalo tady, … Tabulky tě už nezajímají, jsou někde na pozadí, stará se o ně ORM a to automaticky.

Co se týče zboží, nejsem si jistý jestli chápu o co ti jde. Ty totiž předpokládáš, že budeš mít tabulku a ta bude mít relaci na druhou tabulku, ale z tabulek objekty neuděláš.

Takže já ti taky položím otázku: Proč? Rozmysli se co chceš, co to má dělat, jaký to má mít výsledek. Né jak to má být implementované. Pak ti možná budu schopný říct, jak bych to řešil.

Patrik Votoček
Člen | 2221
+
0
-

awsickness napsal(a):

mit entitu a ta by mela umet sama nad sebou pracovat ?

To je případ Doctine ORM 1 kdy to bylo postavené jako Active Record

Doctrine ORM 2 je naopak postaveno na Data Mapperu.

Snažit se Doctrine ORM 2 ohýbat na Active Record je tak trochu drbání se levou nohou za pravým uchem.

mkoubik napsal(a):

To potom není ORM, ale Active Record …

bullshit… AR je taky ORM taky to mapuje objekty s relacema… :-)

Filip111 napsal(a):

… Mj. jsi tam kritizoval mít různý model pro administraci a různý pro frontend, což používám.

Pokud je tím myšlen model jako celek tak je to špatně. Pokud je tím myšlena určitá část (manipulace s datama) tak tam to smysl dává.

Sám ve starších projektech používám dělení Repository vs. Service viz několik článků:

Otázka 1:Otázka 2:

Na obě otázky se dá odpovědět zároveň. V tomhle je právě síla ORM a nejtěžší věc na naučení. Musíš přestat nad daty uvažovat jako o tabulkách v DB. Musíš o nich uvažovat jako o entitách.

Entity ti totiž umožní třeba tohle: http://www.doctrine-project.org/…mapping.html :-)

Filip111
Člen | 244
+
0
-

Já zatím opravdu nevím co chci/co dál :(

Pročetl jsem dneska většinu českého internetu zmiňující Doctrine2, k tomu samozřejmě argumenty Doctrine2 versus notORM/Dibi a vůbec všechno co jsem našel v cz.
Samozřejmě jsem nezapomněl ani na dokumentaci Doctrine2 a pár anglických článků.

Když bych Doctrine2 použil, potřeboval bych pracovat s vícejazyčnými entitami…několikrát jsem narazil na názor, proč to vymýšlet, když už je to vyřešené v Gedmo.
Pak jsem si vzpětí přečetl článek o tom, jak je špatné masivně používat frameworky a ještě je rozšiřovat o další frameworky a rozšíření třetích stran apod.

Výsledkem je, že bych s Doctrine2 rád začal, ale nevím jak jednoduše vyřešit elementární věci např. vytvoření entity článku, který je vícejazyčný apod.

Také se děsím propojení, které je nyní v libs a především údržby do budoucna…Nette, Doctrine, Kdyby, Symphony k tomu možná Gedmo (nebo Nella..abych nezapomněl :).
To je přece šílený – chvilku nebudu koukat na změny ve vývoji a při nejbližším updatu jedné z komponent/frameworku se to rozsype jak domeček z karet (anebo u toho budu týden sedět jen abych to zase na pár měsíců rozhýbal).

Možná to dopadne jako s Nette…půl roku o tom budu uvažovat, pak to zkusím, první měsíc budu přepisovat pořád dokola stejný kódy aby byly lepší a lepší a nakonec budu rád že jsem se to naučil a začal používat.

Editoval Filip111 (12. 1. 2012 21:28)

Filip Procházka
Moderator | 4668
+
0
-

Well, Kdyby není ready na produkci, takže je to zatím spíše na hraní ;)

Co se týče Doctrine 2, tak ta se zase tak moc nemění a docela si i drží zpětnou kompatibilitu a mají dobrý changelog.

Ohledně více frameworků, já mám na projektu teď 4 frameworky a asi 7 dalších knihoven :) Hrůzné, že? Ani ne, protože je nikdy nepoužívám v jeden moment všechny zároveň. Vždycky jen co se týká jedné části aplikace.

Filip111
Člen | 244
+
0
-

Jsem zatím ve fázi zkoušení Doctrine a hledání řešení konkrétních úloh. S čím si nevím rady po prostudování dokumentace a shlédnutí několika screencastů je vícejazyčnost. Chtěl bych to zkusit bez Gedmo rozšíření – především, protože se tu o něm moc nemluví (neví?) a nechci zbytečně zanášet do projektu další závislost na nějakém rozšíření.

Konkrétně: potřebuji vytvořit entitu Categories, která bude mít vlastnosti id a status a potom jazykově závislé lang a title.

Nevím jak toho docílit – zatím se mi podařilo vytvořit entitu, která není plochá ale má id, status a texts což je pole hodnot lang a title.

/**
 * @Entity
 * @Table(name="eshop_categories")
 */
class Categories extends \Nette\Object
{
    public function __construct()
    {
	$this->texts = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * @id @column(type="integer")
     * @generatedValue
     */
    private $id;

    /* @column(type="boolean") */
    private $status;

    /**
     * @var CategoriesText
     * @OneToMany(targetEntity="CategoriesText", mappedBy="eshop_categories_text", cascade={"persist"})
     *
     */
    private $texts;
}


/**
 * @Entity
 * @Table(name="eshop_categories_text")
 */
class CategoriesText extends \Nette\Object
{
    /**
     *
     * Store a reference to the category
     * @id
     * @column(type="integer", nullable="false")
     * @ManyToOne(targetEntity="Categories", inversedBy="texts")
     * @JoinColumn(name="id", referencedColumnName="id")
     */
    private $id;
    /**
     * @id @column(type="string")
     * @Column(length=2)
     */
     private $lang;

    /* @column(type="string") */
    private $title;
}

Ani ta ale nefunguje správně – když vygeneruji sql dump schámatu, vytvoří to následující SQL:

CREATE TABLE eshop_categories (
	id INT AUTO_INCREMENT NOT NULL,
	PRIMARY KEY(id)
) ENGINE = InnoDB;
CREATE TABLE eshop_categories_text (
	id INT NOT NULL,
	lang VARCHAR(2) NOT NULL,
	PRIMARY KEY(id, lang)
) ENGINE = InnoDB

1) Nevíte proč tam chybí polovina sloupců definovaných v entitě?
2) Za předpokladu, že se smířím s tím, že texty budou pro entitu Categories přístupné přes vlastnost texts, je deklarace této entyty správně?
3) Jak bych měl definovat entity Categories, abych dostal plochou strukturu, id, status, lang, title?

pro názornost jsem vyházel set a get metody a spoustu polí.

Díky.

Aurielle
Člen | 1281
+
0
-
  1. U minimálně dvou sloupců ti chybí komentáře ve stylu phpDoc – tedy /** (ty dvě hvězdičky tam prostě musí být)
  2. Správnost definic entit si můžeš ověřit přes CLI interface Doctrine 2.
Filip Procházka
Moderator | 4668
+
0
-

PhpDoc komentáře začínají /**, né /*

Co se týče těch jazyků, na to je v Doctrine 2 nová feature, filtry na dotazy. Není ale ještě zdokumentovaná.

Filip111
Člen | 244
+
0
-

ad 1) aha, hvězdičky..po opravě to vygeneruje správný sql dump

ad 2) v dokumentaci cli jsem našel akorát generate-entity ale nic co by entitu jen zkontrolovalo
Nicméně u této otázky mi šlo spíš o kontrolu mojí úvahy – použití joinu a zvolení vztahu ManyToOne

@HosipLan:
ad 3) Nenašel bys nějaký odkaz, který by mě nasměroval – zkoušel jsem něco googlit, ale nenašel jsem nic relevantního.
Je to pro mě stěžejní věc bez které se dál nehnu – asi 80% objektů, které mám v databázi jsou jazykově závislé – mají dělený obsah do dvou tabulek. Dokud tohle nebudu umět v Doctrine efektivně vyřešit, můžu na ní (na ně?) zapomenout.

Díky.