Funkce pro routy bez dibi
- Radimorous
- Člen | 30
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;
}
- Radimorous
- Člen | 30
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
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 | 799
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
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.
- Radimorous
- Člen | 30
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
Pokud to nezna tridu clanky, tak by jsi ji měl vytvořit, ne? A popřípadě smazat cache.
- Radimorous
- Člen | 30
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
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 | 799
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
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
Též si myslím, že třída model (ať v quickstartu, či porůznu) buď blbě napsaná, nebo zbytečná (u malých aplikací)