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.
Blizard
Člen | 45
+
0
-

Zdravím, mám problém s připojením k databázi z modelu. Stejný problém jsem řešil v Authenticator.php, kde se to nějak záhadně vyřešilo samo. Viz kód.

Chyba kterou mi to hází je „Argument 1 passed to AdminModule\BaseModel::__construct() must be an instance of DibiConnection, none given, called in C:\xampp\htdocs\app\AdminModule\models\CategoryModel.php on line 11 and defined“.

Pro ty kdo by mi chtěli říct že si to mám přeložit jsem již udělal viz config.neon.

Měl jsem vzato, že DibiConnection si ten konstruktor vezme automaticky. Když mi došlo že ne, tak jsem v configu dal jako parametr právě ono připojení a stále to hází stejnou chybu, kterou mi to dělalo u Authenticatoru, ale později už to nedělalo a vůbec nemám tušení proč.

config.neon:

common:
	php:
		date.timezone: Europe/Prague
		zlib.output_compression: yes

	nette:
		application:
			errorPresenter: Error

		session:
			expiration: 14 days

		debugger:
			bar:
					- Nette\DI\Diagnostics\ContainerPanel
	parameters:
		database:
			host: localhost
			username: blizard
			password: *****
			database: test
			charset: utf8
			profiler: true
			lazy: TRUE

	services:
		database:
			class: \DibiConnection(%database%)
		authenticator:
			class: \AdminModule\Authenticator(@database)
			#arguments: [@dibi.connection]
		baseModel:
			class: \AdminModule\BaseModel(@database)
			arguments: [@database]
		categoryModel:
			class: \AdminModule\CategoryModel(@database)
			#arguments: [@dibi.connection]

v bootstrap mám klasicky rozšíření:

// Načtení knihovny dibi
$configurator->onCompile[] = function ($configurator, $compiler) {
    $compiler->addExtension('dibi', new DibiNetteExtension);
};

Přikládám authenticator v kterém mi to funguje:

namespace AdminModule;

use Nette,
    Nette\Security as NS;

class Authenticator extends Nette\Object implements NS\IAuthenticator
{
    /** @var \DibiConnection */
    private $db;

    public function __construct(\DibiConnection $connection)
    {
        $this->db = $connection;
    }

k němu LoginPresenter:

	public function logInFormSucceeded(Form $form)
	{
		try {
			// Zaregistrujeme autorizátor který nám provede validaci údajů ze strany databáze
			$this->user->setAuthenticator($this->context->authenticator);

a následně BaseModel v kterém to už nejde:

namespace AdminModule;

use Nette;

class BaseModel extends Nette\Object
{
    /** @var \DibiConnection */
    protected $db;

    public function __construct(\DibiConnection $connection)
    {
		$this->db = $connection;
    }
}

CategoryModel:

namespace AdminModule;

use Nette;

class CategoryModel extends BaseModel
{
	public function __construct()
	{
	    parent::__construct();
	}

CategoryPresenter:

namespace AdminModule;

use \Nette\Application\UI\Form,
    \Nette\Utils\Html,
    \Nette\Diagnostics\Debugger,
    \nette\Application;

class CategoryPresenter extends BasePresenter {

	/** @persistent int */
	public $id;
	/** @var AdminModule\Category */
	private $categories;

	public function inject(\AdminModule\CategoryModel $category) {
		if ($this->categories) {
			throw new Nette\InvalidStateException('Kategorie již byly nastaveny');
		}
		$this->categories = $category;
	}

Budu moc rád když mi někdo poradí jak to vyřešit. Řeším to už poměrně dlouho..

Editoval Blizard (4. 12. 2013 10:39)

jiri.pudil
Nette Blogger | 1032
+
0
-

Ona ta hláška je dostatečně výmluvná. V CategoryModel voláš konstruktor předka (BaseModel), aniž bys mu předal požadovanou instanci DibiConnection. V tomto případě můžeš metodu CategoryModel::__construct() celou smazat, pokud bys ale chtěl přidávat do CategoryModel další závislosti, musel bys závislost na DibiConnection uvést explicitně znovu a předat ji do konstruktoru předka:

public function __construct(\DibiConnection $db, ...)
{
	parent::__construct($db);
}
Blizard
Člen | 45
+
0
-

jiri.pudil napsal(a):

Ona ta hláška je dostatečně výmluvná. V CategoryModel voláš konstruktor předka (BaseModel), aniž bys mu předal požadovanou instanci DibiConnection. V tomto případě můžeš metodu CategoryModel::__construct() celou smazat, pokud bys ale chtěl přidávat do CategoryModel další závislosti, musel bys závislost na DibiConnection uvést explicitně znovu a předat ji do konstruktoru předka:

public function __construct(\DibiConnection $db, ...)
{
	parent::__construct($db);
}

Děkuji, problem prozatím vyřešen.