Volání modelu z presenteru, modely jako továrny?

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

Ahoj,
měla bych otázku ohledně modelu a sql dotazů. Zatím mám vše řešené podle nového Quickstartu, takže mám modely registrované jako továrny a v presenteru stavím dotazy pomocí

<?php
$this->context->createCategories()...
?>

Ale nevím, jestli se toto řešení normálně používá. V modelu skoro nic nemám, všechny dotazy mám v presenteru a například složité selecty nebo rekurzivní dotazy nevím, jak bych pomocí API řešila. Co tedy s těmito složitými dotazy? Zkusila jsem napsat funkci v jednom z modelů:

<?php
class Components extends Selection {

    private $database;

    public function __construct(Connection $connection) {
        parent::__construct('component', $connection);
        $this->database = $connection;
    }

    public function getComponents($id) {
        return $this->database->query(...);
    }
}
?>

ale teď nevím, jak to z presenteru zavolat. Myslela jsem něco jako:

<?php
$this->context->getComponents($id);
?>

ale toto hlásí to chybu: Call to undefined method SystemContainer::getComponents(). Je vůbec správný tento způsob? Procházela jsem fórum i dokumentaci, ale přišlo mi, že toto každý řeší úplně jinak. Díky moc za rady.

Vojtěch Dobeš
Gold Partner | 1316
+
0
-

Zkusím to trošičku rozepsat: model je ta část aplikace, která obsahuje nějakou tu faktickou logiku. Takže principielně ta metoda getComponents() je určitě ok (i když si nejsem jist, proč dědí od Selection, to je postup z Nette\Database?).

Teď jde o to, že v konfiguračním souboru si lze tyto třídy zaregistrovat buď jako služby (services) nebo továrničky (factories). Předpokládám, že tvoji třídu Components stačí vytvořit jednou a pak jde hlavně o to volat na ní (třeba víckrát) onu metodu getComponents().

Správný postup je tedy zaregistrovat tuto třídu jako službu:

services:
	components:
		class: Components

Přístupná je pak v presenteru jako:

$this->context->components

A na ní lze volat onu metodu:

$this->context->components->getComponents(...
janycta
Člen | 12
+
0
-

Ahá! Tak použití služby místo továrničky pomohlo, díky moc!

i když si nejsem jist, proč dědí od Selection, to je postup z Nette\Database?

To je postup z Quickstartu:

Při vytváření modelu vytvoříme pro každou tabulku jednu třídu, která jí bude reprezentovat. Protože Nette\Database již má základní databáze operace naimplementované ve třídě Nette\Database\Table\Selection, můžeme jí celkem pěkně využít.

Ještě mě napadá, kdy je tedy dobré použít služby a kdy továrničky?

Jan Endel
Člen | 1016
+
0
-

No ideální je vysvětlit to na příkladě, máme třídu NakladacDreva a Drevo pokud budeme pracovat s Nakladacem tak ho použijeme jako službu, protože může naložit kolik dřeva jenom chce (odbory, přesčasy a únavu teď pomineme). Kdežto na Drevo potřebujeme factory protože poté, co ho zpracujeme do podoby židle nebo stolu už nejde vrátit do původní podoby a musíme vzít nové.

Glottis
Člen | 129
+
0
-

analogii chapu ale nejak si to v aplikaci predstavit neumim :) neslo by to jeste jednou pro jeste pomalejsi? :) dik

ricco24
Člen | 141
+
0
-

Podľa toho ako som to pochopil z dokumentácie a pilec-ovho postu by to malo byť jednoducho vysvetlené takto:

DI kontajner implemenovaný v nette service vytvára iba raz takže každé volanie nám vracia rovnakú instanciu kďežto v prípade ak použijeme factory vytvárame vždy novú instanciu.

Chápem to správne ? :)

Jan Endel
Člen | 1016
+
0
-

@ricco24: chapes spravne.

janycta
Člen | 12
+
0
-

Díky všem za odpovědi ;-)