Chyba v Quickstartu – nedefinovaný find()

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

Dobrý den,
chci jen poukázat na chybu v quickstartu a zeptat se jak ji vymazat. V kapitole Presentery a šablony máme udělat toto:

public function actionDefault($id)
{
    $this->list = $this->listRepository->find($id);
}

jenže funkce find() není definovaná a proto to hází chybu. Co s tím?

.:M@rt!n:.
Člen | 201
+
0
-

Musíš ji v ListRepository napsat. Řekneš jí dotazem nad db co má najít.

Yohaku
Člen | 18
+
0
-

Tak jsem to udělal takto:

public function find($id)
{
    return $this->findOneBy(array('id' => $id));
}

Ale píše to tuto chybu:
Argument 1 passed to Todo\ListRepository::tasksOf() must be an instance of Nette\Database\Table\ActiveRow, boolean given, called in…

mildabre
Člen | 62
+
0
-

Přesně stejný problém jse také řešil – metoda find() v modelu. Tutoriál pro začátečníky je zde v tomto místě nekompletní a když se postupuje podle návodu tak aplikace nefunguje. Již si přesně nepamatuji co přesně se muselo změnit, ale našel jsem si třídu Repository která mě funguje, zde je:

<?php
namespace Todo;
use Nette;

/**
 * Provádí operace nad databázovou tabulkou.
 */
abstract class Repository extends Nette\Object
{
    /** @var Nette\Database\Connection */
    protected $connection;

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

    /**
     * Vrací objekt reprezentující databázovou tabulku.
     * @return Nette\Database\Table\Selection
     */
    protected function getTable()
    {
        // název tabulky odvodíme z názvu třídy
        preg_match('#(\w+)Repository$#', get_class($this), $m);
        return $this->connection->table(lcfirst($m[1]));
    }

    /**
     * Vrací všechny řádky z tabulky.
     * @return Nette\Database\Table\Selection
     */
    public function findAll()
    {
        return $this->getTable();
    }

    /**
     * Vrací řádky podle filtru, např. array('name' => 'John').
     * @return Nette\Database\Table\Selection
     */
    public function findBy(array $by)
    {
        return $this->getTable()->where($by);
    }

    public function findOneBy(array $by)
    {
        return $this->findBy($by)->limit(1)->fetch();
    }

    public function find($id)
    {
        return $this->findOneBy(array('id'=>$id));
    }
}

?>

Ještě mne napadá, že možná máš už ty modelové metody OK, ale ta chyba je způsobena tím, že je tabulka prázdná, nebo pro zadané id neexistuje v atbulce záznam – potom ta metody vrátí boolean. Ten boolean by jsi měl ošetřit nějakou výjimkou nebo poslat na výstup jinou šablou s odpovídající zprávou.

Montes
Člen | 5
+
0
-

@mildabre
Diky moc, funguje to!

thunderbuff
Člen | 164
+
0
-

Find lze zjednodušit na:

<?php

public function find($id) {
	return $this->getTable()->find($id)->fetch();
}

?>
roarbb
Člen | 29
+
0
-

Tak aj ja pridam svoj kus kodu :)

Find lze zjednodušit na:

public function find($id)
{
    return $this->getTable()->get($id);
}
Šaman
Člen | 2666
+
0
-

Když už se to řeší něco podobného, tak nahodím konvenci, kterou jsem se naučil v ORMu Petra Procházky.

FIND vrací kolekci (pole, datasource, ..), může být i prázdná. Tedy lze vždy iterovat.
GET vrací vždy jeden záznam (entitu), nebo NULL.

Když nemáte nějakou takovouhle (či jinou, ale pevnou) konvenci, vznikají wtf situace.