Přístup k databázi v modelu
- Fandik
- Člen | 19
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
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
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
A ModelLoader by nebylo řešení? Zkus pohledat na fóru, jestli to pro tebe není to pravé ořechové…
- Filip Procházka
- Moderator | 4668
Pokud ti nevoní Dependency Injection
, není přece problém
zůstat u Nette\Environment
ne?