Funkce pro routy bez dibi

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

V bootstrap mám:

$router[] = new Route('clanek/<id>', array(
        'presenter' => 'Homepage',
        'action' => 'clanek',
        'id' => array(
                        Route::VALUE => 0, // default value
                        Route::FILTER_OUT => callback('Model::getTitleById'),
                        Route::FILTER_IN => callback('Model::getIdByTitle'),
       )));

Funkce v modelu je:

public static function getTitleById($id)
   {
       return self::getConnection()->fetchSingle('
           SELECT [url_clanku]
           FROM [clanky]
           WHERE [id]=%i', $id);
   }

Jak funkci getTitleById($id) přepíšu, když aktuálně chci používat Nette 2.0 bez dibi (v novém Quick startu to je již bez dibi) a mám v modelu zatím jen:

public function __construct(Nette\Database\Connection $database)
{
    $this->database = $database;
}
mkoubik
Člen | 728
+
0
-

Použij callback($model, 'getTitleById') a $model si vytáhni z kontejneru.

Radimorous
Člen | 30
+
0
-

mkoubik napsal(a):

Použij callback($model, 'getTitleById') a $model si vytáhni z kontejneru.

Můžeš prosím ještě napsat, jak si mám $model vytáhnout z kontejneru?

Radimorous
Člen | 30
+
0
-

Radimorous napsal(a):

mkoubik napsal(a):

Použij callback($model, 'getTitleById') a $model si vytáhni z kontejneru.

Můžeš prosím ještě napsat, jak si mám $model vytáhnout z kontejneru?

Případně nebude pro úplného začátečníka s Nette jednoduší pracovat s dibi? To snad aspoň trošku bude někde popsaný doufám… U routování s Nette DB jsem strávil odpoledne a večer a pořád na to nepřišel…

uestla
Backer | 796
+
0
-

Píši z paty, ale osobně bych to vyřešil např. takto (mj. doporučuji podívat se i na nový QuickStart):

Uvažuju z tvého popisu využití třídy Model (z dřívější verze sandboxu).

Model.php

class Model extends Nette\Object
{
	// ...

	public function getClanky()
	{
		return new Clanky('clanky', $this->database);
	}
}

Clanky.php

class Clanky extends Nette\Database\Table\Selection
{
	function getTitleById($id)
	{
		return $this->find($id)->select('url_clanku')->fetch()->url_clanku;
	}

	function getIdByTitle($title)
	{
		return $this->select('id')->where('url_clanku', $title)->fetch()->id;
	}
}

bootstrap.php

$router[] = new Route('clanek/<id>', array(
	'presenter' => 'Homepage',
	'action' => 'clanek',
	'id' => array(
		Route::VALUE => 0, // default value
		Route::FILTER_OUT => callback($container->model->clanky, 'getTitleById'),
		Route::FILTER_IN => callback($container->model->clanky, 'getIdByTitle'),
	),
));

Snad jsem spíše pomohl než uškodil…

Editoval uestla (27. 12. 2011 1:42)

Radimorous
Člen | 30
+
0
-

uestla: díky. Teď mi to píše, že to nezná třídu Clanky, když jsem to zkusil podle Tvého postupu tady. Nový Quick start jsem procházel celý, tohle v něm však není – spíš bych potřeboval aktualizovaný tutorial na blog, kde by se nevyužívalo dibi, ale nette DB.

uestla
Backer | 796
+
0
-

Nový quick start jsem doporučoval spíše pro zdroj postupů, jak pracovat s Nette\Database a různě k ní z aplikace přistupovat.

Smazal jsi cache? Vytvořil sis soubor Clanky.php s třídou Clanky uvnitř?

Radimorous
Člen | 30
+
0
-

uestla napsal(a):

Nový quick start jsem doporučoval spíše pro zdroj postupů, jak pracovat s Nette\Database a různě k ní z aplikace přistupovat.

Smazal jsi cache? Vytvořil sis soubor Clanky.php s třídou Clanky uvnitř?

Tak chyba byla v tom, že jsem nesmazal cache. Po zhruba pěti hodinách nadávání to je pozitivní zjištění :-) Ještě jednou díky eustla za tento postup!

Filip Procházka
Moderator | 4668
+
0
-

Pokud to nezna tridu clanky, tak by jsi ji měl vytvořit, ne? A popřípadě smazat cache.

Radimorous
Člen | 30
+
0
-

Tak přeci jen routování ještě nefunguje jak má, když jsem to udělal podle uestla, viz výše (title jsem nahradil za url). První odkaz se provede v pořádku, u druhého mi laděnka píše, že sql vypadalo následovně:

SELECT `url`, `url` FROM `obsah` WHERE (`id` = ?) AND (`id` = ?)

Vloží se tam parametry dvakrát, pak to vrátí 0 řádků a je error. Netuší někdo, jak se mohly parametry dostat do sql dvakrát?

Editoval Radimorous (30. 12. 2011 0:42)

Radimorous
Člen | 30
+
0
-

Pro jistotu přidám ještě kod.
class Stranky

class Stranky extends Nette\Database\Table\Selection
{
        function getUrlById($id)
        {
                return $this->find($id)->select('url')->fetch()->url;
        }

        function getIdByUrl($url)
        {
                return $this->select('id')->where('url', $url)->fetch()->id;
        }
}

model

public function getStranky()
{
  return new Stranky('obsah', $this->database);
}

bootstrap

$router[] = new Route('<action>/[<id>]', array(
        'presenter' => 'Homepage',
        'action' => 'podstranka',
        'id' => array(
                Route::VALUE => 1, // default value
                Route::FILTER_IN => callback($container->model->stranky, 'getIdByUrl'),
                Route::FILTER_OUT => callback($container->model->stranky, 'getUrlById'),
        ),
));

Skonci to chybou, kdy se do sql (netusim jak) dostane url dvakrat – viz vyse.

uestla
Backer | 796
+
0
-

Jojo, právě o tom se mluvilo – ty podmínky se řetězí pro každou instanci Selection (i když nevím, jaktože ti to nevytváří pro oba přístupy ke $container->model->stranky pokaždé novou instanci…).

David psal, že se od třídy Model máme odprostit a naplno využít DI, čili bych navrhl ještě „konkurenční“ řešení ;-)

config.neon

common:
	# ... @database, @session, ...

	factories:
		obsah: @database::table('obsah')

bootstrap.php

$router[] = new Route('<action>/[<id>]', array(
	'presenter' => 'Homepage',
	'action' => 'podstranka',
	'id' => array(
		Route::VALUE => 1, // default value
		Route::FILTER_IN => function ($url) use ($container) {
			return $container->createObsah()->select('id')->where('url', $url)->fetch()->id;
		},
		Route::FILTER_OUT => function ($id) use ($container) {
			return $container->createObsah()->find($id)->select('url')->fetch()->url;
		},
	),
));
Radimorous
Člen | 30
+
0
-

uestla: Druhej „konkurenční“ způsob již funguje výborně, díky za něj! Tento kod by se hodilo vykopírovat i do manuálu k routám a do Quick Startu, ať to začátečníci mají jednoduší :)

bojovyletoun
Člen | 667
+
0
-

Též si myslím, že třída model (ať v quickstartu, či porůznu) buď blbě napsaná, nebo zbytečná (u malých aplikací)