NotORM\Connection – ako jednoducho pripojiť NotORM

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

Keďže Nette\Database má len základnú funkcionalitu a hodí sa len na jednoduché príklady a netuším, kedy budú nové vlastnosti z NotORM implemetované do Nette\Database, vytvoril som si pre vlastnú potrebu jednoduchú maličkú NotORM\Connection, ktorá využíva všetky možnosti NotORM v Nette podobne jednoducho ako Nette\Database. Skúšal som to na aktuálnom nette-dev a sandboxe (15.8.2011).

Vychádzal som zo srigiho kuchárky a snáď som aj správne pochopil a použil DI. Moja implementácia tiež obsahuje Debugger panel. Na rozdiel od srigiho sa dá v NotORM\Connection nastaviť vlastná NotORM_Structure a NotORM_Cache a hlavne sa tu nevyrábajú žiadne zbytočné modely ;-) ale je možné použiť priamo NotORM connection v celej aplikácii.

Ako na to?

1. krok

Vo svojom projekte do nette/libs si umiestnite notorm/notorm_connection/

2. krok

Na základnú konfiguráciu treba mierne upraviť config.neon:

	connection:
		class: NotORM\Connection
		arguments: ['mysql:host=localhost;dbname=sample-db', 'root', '']

	notorm:
		factory: [@connection, getNotORM]

Toto stačí na základnú funkcionalitu NotORM v Nette.

Od teraz bude služba notorm prístupná klasicky cez: $this->context->notorm. Pokiaľ vám stačí východzie nastavenie NotORM, nemusíte už nič viac urobiť.

3. krok

Službu notorm je ďalej možné konfigurovať cez parametre a pridať jej vlastné cache alebo structure:

	services:
		...
		connection:
			class: NotORM\Connection
			arguments: ['mysql:host=localhost;dbname=sample-db', 'root', '']

		notorm:
			factory: [@connection, getNotORM]
			arguments: [@notorm_structure, @notorm_cache]

		notorm_structure:
			class: NotORM_Structure
			arguments: ['id', '%s_id', '%ss']

		notorm_cache:
			class: NotORM_Cache_Database
			arguments: [@pdo]

		pdo:
			factory: [@connection, getPDO]

4. krok

Pokiaľ potrebujete NotORM nastaviť nejakú dodatočnú konfiguráciu môžete to urobiť v bootstrap.php.

<?php
	......
	$container = $configurator->loadConfig(__DIR__ . '/config.neon');

	// NotORM setup
	$container->notorm->rowClass = 'My_NotORM_Row';
?>

5. krok

Pozor: Milovníci viacvrstvových modelov nech radšej ďalej nečítajú alebo len na vlastné riziko ;-)

Pokiaľ nechcete strácať čas vytváraním viacvrstvových modelov ;-) môžete si jednoducho upraviť BasePresenter napríklad takto:

<?php

abstract class BasePresenter extends Nette\Application\UI\Presenter
{
    /**
     * @var NotORM
     */
    public $notorm;

    protected function startup() {
        $this->notorm = $this->context->notorm;
    }

    protected function beforeRender() {
        $this->template->notorm = $this->notorm;
    }
}

?>

a potom môžete v presenteroch použiť napr:

<?php
	public function renderDefault() {
		$title = $this->notorm->article[$id]['title'];
		// alebo
            	$this->template->article = $this->notorm->article[$id];
	}
?>

a v template len

<?php
	{$article['title']}
?>

6. krok

Teraz môžete spokojne zmazať adresár libs/Nette/Database ;-)

Keby to niekoho zaujímalo dal som to na github.

Download: NotORM\Connection

jenda87
Člen | 20
+
0
-

Ahoj,

tvoje implementace mi pěkně funguje v šablonách i v prezentru. Chtěl bych ale používat proměnnou $notorm i v modelu nějak takto:

class Model extends Nette\Object
{
	....

	public function getObjects() {
		return $this->notorm->objekty();
	}

}

Jde $notorm nějak dostat do modelu při využití konfigurace z config.neon?

zatím to řeším přes:

$M = new Model($this->notorm)

To ale asi není ono.
Srigiho třída mi pro mé použití přijde příliš komplikovaná.

gawan
Člen | 110
+
0
-

@jenda87 ja to používam tak, že nevyrábam žiadne modely a s notorm pracujem rovno v prezenteroch aj v templatoch. Aký je rozdiel, či v prezenteri použiješ model->getObjects() alebo rovno notorm->objekty()? Porozmýšľaj, možno si ušetríš prácu s vyrábaním modelov ;-)

Ak by si mal pocit, že ich predsa len potrebuješ modely pozri sem. Tu je ukážková implemetácia modelu pomocou DI: Dynamické načítání modelů

Editoval gawan (20. 7. 2011 11:34)

Filip Procházka
Moderator | 4668
+
0
-

Mít třídy, které budou zapouzdřovat práci s daty je lepší, protože ti seskupují práci s daty. Říká se tomu také znovupoužitelnost a princip jedné odpovědnosti :)

Když chceš něco změnit, změníš to na jednom místě a nehledáš to v desítkách presenterů, ve kterých to můžeš přehlédnout, nebo mít použité nestandardně, takže ti to vyhledávání výskytů nenajde :)

gawan
Člen | 110
+
0
-

To si práve nemyslím, čo urobíš ak musíš refaktorovať a zmeniť stĺpec v db? Napríklad „name“ na „login“. Potom máš niekde v modely funkciu:

<?php
function getName() {
	return $this->name;
}
?>

potom urobíš čo? len toto?

<?php
function getName() {
	return $this->login?
}
?>

a všetky výskyty funkcie getName() necháš tak ako sú? Nebude z toho potom trochu chaos, že funkcia getName() bude volať $this->login? Ja keď som používal modely, tak som aj tak musel nájsť všetky výskyty getName() a zmeniť ich na getLogin(), inak by to bol strašný chaos. Takže tento argument sa síce často opakuje, ale v praxi som to aj tak menil všade… Máš ešte nejaký iný dôvod na čo je dobré mať modely?

Filip Procházka
Moderator | 4668
+
0
-

Je jedno, že si to nemyslíš, protože nemáš pravdu. V praxi jsi evidentně nikdy neviděl nic složitějšího než

class MySuperDuperModel {
	function najdi($id) {
		return dibi::select('*')->from('table')->where('id = %i', $id)->fetch();
	}
}

Ale abych ti nekřivdil úplně, na webu, kde máš knihu návštěv a anketu se asi dělat modely nevyplatí :)

K tvé otázce: Samozřejmě když udělám takovou změnu, tak musím změnit všechny výskyty.

gawan
Člen | 110
+
0
-

Nemal som v úmysle sa niekoho dotknúť a vyvolať hádku. Momentálne pracujem s db, ktorá má (keď tak pozerám) 117 tabuliek a 406MB a kniha návštev to nie je ;-) Pár rokov už používam modely, kde mám napríklad oddelenú validačnú vrstvu ktorú nezaujíma, či prišli data z formuláru alebo cez nejaké externé XML, o čom môže nette zatiaľ len snívať, lebo má validáciu zadrátovanú do formulárov.

Ale teraz si overujem iný prístup v tvorbe aplikácií, ako vyrábať komplikované modely. Na nette sa mi páči práve to, že tam tá modelová vrstva v podstate nie je. A je mi jasné, že z tvojho pohľadu sa ti zdá, že nemám pravdu. Aj mne by sa to zdalo, keby som vychádzal len z týchto informácií.

To, čo som tu napísal, ešte nie je úplná metodika toho nového prístupu bez modelov, ktorý si skúšam. A ako píšeš, tak ako to je zatiaľ v tomto vlákne podané je to vhodné najmä ma menšie webíky, kde tento bezmodelový prístup stačí a nič iné k tomu netreba pridať. Ja sa snažím tento prístup teraz overiť v praxi na trochu väčšej aplikácii (tých 117 tabuliek), kde si ešte musím niečo z modelovej vrstvy nechať. Práve pracujem na tom, aby som to čo možno najviac minimalizoval. Keď sa mi to osvedčí a bude to fungovať, napíšem o tom viac.

Filip Procházka
Moderator | 4668
+
0
-

V tom případě se omlouvám, že jsem tě podcenil. Samozřejmě neexistuje Jediná správná cesta™. Ale oddělením logiky od prezentace nemůžeš nic zkazit.

Kde mám začít odebírat RSS, abych si pak o tom mohl něco přečíst? :)

gawan
Člen | 110
+
0
-

Áno, oddelenie logiky od prezentácie dodržiavam. Plánujem o tom tu na fóre napísať, pretože to je postavené na nette. Ale ešte si to chcem poriadne preveriť, či to nie je predsa len blbosť, aby som si nespravil hanbu v celom nette vesmíre ;-)

comming soon… this summer … ;-)

Filip Procházka
Moderator | 4668
+
0
-

I špatné řešení je dobré, aby člověk věděl, jak to dělat nemá :) Každopádně se těším ;)

jenda87
Člen | 20
+
0
-

Dle mého názoru se vynechání modelu vyplatí jen u mini projektů.
Už jen když musíš v prezenteru (kdybych vynechal model, tak bych asi vynechal i presenter :-D = fuj) psát stále několik stejných dotazů dokola:

$foo = $db->tabulka1->tabulka2("lala=$lblb);
$foo2 = $db->tabulka1->tabulka3("lala=$lblb);
....

a další, tak je to votrava, když bys musel něco měnit tak ještě větší.

Každopádně stále nevím jak nejlépe připojit NotORM do modelu. Když vytvořím připojení k databázi přes config.neon, tak jediné co mě napadlo je metoda viz výše.

Nebo je lepší vytvořit připojení přímo v modelu?

Filip Procházka
Moderator | 4668
+
0
-

Jednoznačně je jednodušší připojení předávat. Kontrolováním a kradením připojení mezi modely by jsi aplikaci neskutečně zkomplikoval. A nebudu si ani zkoušet představit, jak by to vypadalo, kdyby jsi měl jedno databázové připojení pro každý model…