Přístup k databázi v modelu

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

Zdravím,
vím, že tu je několik podobných příspěvků, ale jelikož jsem v Nette začátečník tak mi moc nepomohly a obracím se na vás s konkrétním dotazem.

Mám několik modelů a potřeboval bych, aby v každém z těchto modelů jsem měl co nejsnažší přístup k databázi.

Všechny modely dědí od BaseModel. Přístup bych si představoval jako přístup k atributu objektu (modelu).

Tzn. v odvozeném modelu:

class UserModel extends BaseModel
{
    public function existUser()
    {
        $db = $this->db;
        $db->query(...);
        ...
    }
}

Tudíž BaseModel:

class BaseModel extends Nette\Object
{
    protected $db;

    public function __construct()
    {
        $this->db = new Nette\Database\Connection('mysql:host=localhost;dbname=test','user','password');
    }
}

Toto je poněkud nešťastné řešení (na produkční serveru se používá jiné nastavení), takže jsem se snažil vytáhnou nastavení do neonu, ale to se mi moc nedaří.

Podle ukázkového příkladu jsem BaseModel upravil takto:

class BaseModel extends Nette\Object
{
    protected $db;

    public function __construct(Nette\Database\Connection $database)
    {
        $this->db = $database;
    }
}

A do neonu jsem přidal:

common:
    services:
        database:
            class: Nette\Database\Connection
            arguments: ["mysql:host=localhost;dbname=test", "user", "password"]
        model:
            class: BaseModel
            arguments: ["@database"]

Někde, ale mám asi logickou chybu, přotože při použití jakéhokoliv modelu mi křičí laděnka: Argument 1 passed to Model::__construct() must be an instance of Nette\Database\Connection, none given…

Je chyba v tom, že se nevytváří instance od BaseModel, ale až od jeho potomků? Jaké je nejlepší řešení?

Filip Procházka
Moderator | 4668
+
0
-

Proč mám pocit, že tam vidíš magii, kterou není technicky možné udělat :)

class UserModel extends BaseModel
{
    public function existUser()
    {
        $db = $this->db;
        $db->query(...);
        ...
    }
}

config

services:
	users:
		class: UserModel
		arguments: [@database]

Všechny modely musíš registrovat jednotlivě, jinak se ti tam to připojení nepředá.

presenter

$this->context->users->existUser()

Editoval HosipLan (5. 7. 2011 14:17)

Fandik
Člen | 19
+
0
-

Všechny modely musíš registrovat jednotlivě, jinak se ti tam to připojení nepředá.

To je to, co nechci dělat, protože není to logicky správně. Když já chci mít v kterémkoliv modelu dostupnou databázi přes $this->db, tak je přece blbost v config.neon každému modulu zvlášť registrovat databázi.

Mým cílem je, aby tu databázi měl přístupnou ihned každný nově vytvořený model a aby mi zároveň nastavení se uchovávalo v config.neon.

Bohužel s DI se mi to nedaří nějak jednoduše zprovoznit. Zatím jsem to udělal s deprecated Nette\Environment, ale je to mnohem stručnější a jednodušší.

config.neon:

common:
    services:
            class: Nette\Database\Connection
            arguments: ["mysql:host=localhost;dbname=test", "user", "password"]

třída BaseModel:

class BaseModel extends Nette\Object
{
    protected $db;

    public function __construct()
    {
        $this->db = Nette\Environment::getService('database');
    }
}

ostatní modely:

class otherModel extends BaseModel
{
	public function test()
	{
		$db = $this->db;
		$db->query(...);
		...
	}
}
BigCharlie
Člen | 283
+
0
-

A ModelLoader by nebylo řešení? Zkus pohledat na fóru, jestli to pro tebe není to pravé ořechové…

hAssassin
Člen | 293
+
0
-

@Fandik > jj ModelLoader je asi best na tohle… Sam sem si to implementoval a zatim si nestezuju. Inspiraci sem hledal tu a tu .

Fandik
Člen | 19
+
0
-

Jako náhrada Nette\Environment je to asi to nejlepší co se dá použít, takže děkuji za radu, vyzkouším to.

22
Člen | 1478
+
0
-

To není náhrada, to je DI.

Filip Procházka
Moderator | 4668
+
0
-

Pokud ti nevoní Dependency Injection, není přece problém zůstat u Nette\Environment ne?