Přístup do databáze z modelu [dibi]

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

Dobrý den,

přeprogramovávám svůj původní projekt z bezframeworkové struktury do Nette -
Nette verze 2.1, Dibi verze 2.1.1

a mám následující problém: Potřebuji umožnit modelu (Users.php) aby mohl přistupovat do databáze (pomocí Dibi). Model (Users.php) zatím vypadá takto:

namespace App;

use Nette,
	Nette\Environment;

class UsersModel extends Nette\Object
{

	public $database;

    function __construct(\DibiConnection $database)
    {
        $this->database = $database;
    }

    function checkUsernameAvailability($username)
    {

        $row = $this->database->select("username")->from('users')->where('username = %s', $username)->fetchSingle();

        if (!$row) {
            return true;
        }

		// return data
        return false;
    }
}

config.neon vypadá takto:

parameters:

	dibi:
		driver: mysqli
		host: mujserver
		username: uzivatel
		password: heslo
		database: databaze
		profiler: true

	/// nejaká dalsi konfigurace ///

services:
	- App\RouterFactory
	router: @App\RouterFactory::createRouter

	database:
		class: DibiConnection
		create: dibi::connect(%dibi%)
		run: true

	authenticator: App\UserAuthenticator(@database, users)
	users: App\UsersModel(@database, users)

Authenticator mi funguje, ale UsersModel ne, píše mi to následující chybu:

Argument 1 passed to App\UsersModel::__construct() must be an instance of DibiConnection, none given...

Chyba je v tomto:

function __construct(\DibiConnection $database, $table)

Proč? Už se s tím štvu 20 hodin, projel jsem půl Googlu, svou konfiguraci změnil 50× a stále se nemůžu dopátrat, co dělám špatně, že stále vidím jen chybu a ne požadovaný výsledek.

Editoval dj.kure (6. 1. 2014 18:09)

vvoody
Člen | 910
+
0
-

Na začiatok otázka: v súbore Users.php máš triedu UsersModel? To ale asi bude preklep, inak by to asi vyhadzovalo inú chybu.

David Matějka
Moderator | 6445
+
0
-

nejdriv pises

function __construct(\DibiConnection $database)

a pak

function __construct(\DibiConnection $database, $table)

tak jak teda? 

@vvody: pokud na to vidi RobotLoader, tak je to jedno. ale mas pravdu, ze by to melo byt konzistentni..

dj.kure
Člen | 70
+
0
-

V Users.php mám

class UsersModel

Mám slovíčko „Model“ úplně vypustit? Myslel jsem, že je to lepší pro zachování čistoty.

Proměnnou $table úplně vypusťte, už tam není.

David Matějka
Moderator | 6445
+
0
-

spis jde o to, aby to bylo konzistentni – kdyz se trida jmenuje UsersModel, tak aby se soubor jmenoval UsersModel.php.. (ja teda to slovo „Model“ v nazvech konkretnich trid nemam rad, je hrozne obecny). ale to nebude problem. takze klasicka otazka: zkousel si smazat cache?

jinak, v configu nemusis specifikovat @database, nette autowiring se postara o nalezeni zavislosti sam

Milo
Nette Core | 1283
+
0
-

@dj.kure Konfiguraci si můžeš zjednodušit:

database: DibiConnection(%dibi%)
users: App\UsersModel(@database, users)

v případě, že konstruktor UsersModel je

public function __construct(\DibiConnection $db, $table) {}

Kde a kdy Ti ta chybová hláška vyskočí?

Editoval Milo (6. 1. 2014 20:29)

dj.kure
Člen | 70
+
0
-

Ano, @database byla už jen taková … „nouze z nouze“, dal jsem to pryč, nic se nezměnilo.

Slovíčko Modul jsme tedy úplně vypustil, už máme jen Users.php, v něm třídu Users

class Users extends Nette\Object

konstruktor této třídy tedy vypadá takto:

public $database;

function __construct(\DibiConnection $database)
{
    $this->database = $database;
}

Cache promazána, žádná změna.
Pořád nechápu, co mám špatně :-(

David Matějka
Moderator | 6445
+
0
-

kde a jak pristupujes k App\Users?

dj.kure
Člen | 70
+
0
-

Přistupuji v rámci RegistrationPresenteru, kde funkce usernameValidator ověřuje (použita jako callback pro form), zda při registraci ve formuláři není vyplněno již použité uživatelské jméno – tj.

public function usernameValidator($username)
{
	$users = new Users;
	return $users->checkUsernameAvailability($username->value);
	//dump($username->value);
}

Editoval dj.kure (6. 1. 2014 20:47)

David Matějka
Moderator | 6445
+
0
-

tu sluzbu si musis injectnout https://forum.nette.org/…-v-nette-2-1#…

dj.kure
Člen | 70
+
0
-

matej21 napsal(a):

tu sluzbu si musis injectnout https://forum.nette.org/…-v-nette-2-1#…

Z výrazu „Foo“ nebo „Bar“ v odkazovaném článku nepoznám co si mám myslet, nebo jak to použít.
Jak by to mělo tedy vypadat v mém případě? :-/ Začíná se mi ta věc dost protivit svou složitostí, vždyť nechci nic složitého, jen jednu funkci která vrátí na základě dotazu z DB ANO/NE, nic víc :(

David Matějka
Moderator | 6445
+
0
-

foobar

/**
* @var \App\Users
* @inject
*/
public $users;
dj.kure
Člen | 70
+
0
-

Děkuju, jsem omezenec, nebo možná úplnej idiot, už mi to funguje:

	/**
	* @var \App\Users
	* @inject
	*/
	public $users;

	public function injectUsers(\App\Users $users)
	{
	$this->users = $users;
	}

	public function usernameValidator($username)
	{
		return $this->users->checkUsernameAvailability($username->value);
	}

Ještě jednou děkuju.

mkoubik
Člen | 728
+
0
-

Když tam máš tu anotaci @inject tak už nepotřebuješ tu metodu injectUsers().

Buď:

/**
* @var \App\Users
* @inject
*/
public $users;

nebo:

private $users;

public function injectUsers(\App\Users $users)
{
    $this->users = $users;
}
dj.kure
Člen | 70
+
0
-

mkoubik napsal(a):

Když tam máš tu anotaci @inject tak už nepotřebuješ tu metodu injectUsers().

Buď:

/**
* @var \App\Users
* @inject
*/
public $users;

nebo:

private $users;

public function injectUsers(\App\Users $users)
{
    $this->users = $users;
}

Díky, pravda, opraveno :-)