Nette + NotORM – základní výpis

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

Zdravím,
snažím se rozchodit NotORM, ale nedaří se mi nic vypsat. Vychazím z https://pla.nette.org/…cy-injection. Už se v tom vrtám strašně dlouho, tak se obracím na Vás. Cílem je vypsat uživatele. Chybu vidím asi někde v tom fetch, jelikož si nejsem jistý jak to správně použít. Díky.

config

common:
	parameters:

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

	nette:
		application:
			errorPresenter: Error

		database:
			dsn: 'mysql:host=wm31.wedos.net;dbname=db'
			user: ''
			password: ''

		session:
			expiration: 14 days


	services:
		dbcache: NotORM_Cache_Include("%tempDir%/notorm.cache")
		database: NotORM(@\PDO, NULL, @dbcache)
		authenticator: Authenticator
		userModel: ProjectManagement\User
		routerFactory: RouterFactory
		router: @routerFactory::createRouter


	factories:


production < common:

development < common:

model – Base

<?php
namespace ProjectManagement;

use Nette;
use NotORM;

abstract class Base extends Nette\Object
{
    /** @var NotORM */
    protected $db;

    /** @var string */
    private $tableName;


    /**
     * @param NotORM
     */
    public function __construct(NotORM $notorm)
    {
        $this->db = $notorm;
        $this->tableName = $this->tableNameByClass(get_class($this));
    }


    /**
     * Určí tabulku dle názvu třídy
     * @param string
     * @return string
     * @result: Pages => pages, ArticleTag => article_tag
     */
    private function tableNameByClass($className)
    {
        $tableName = explode("\\", $className);
        $tableName = lcfirst(array_pop($tableName));

        $replace = array(); // A => _a
        foreach (range("A", "Z") as $letter) {
            $replace[$letter] = "_" . strtolower($letter);
        }

        return strtr($tableName, $replace);
    }


    // přidáme vlastní metody: insert, update, delete, count,
    // fetchSingle, fetchPairs atd.

}

model – User

<?php
namespace ProjectManagement;
use Nette;

/**
 * Tabulka users
 */
class User extends Base
{
    /**
     * Return user by name
     * @param string
     */
    public function getByName($name)
    {
        return $this->db->user("name", $name)->fetch();
    }
}

HomePresenter

<?php

/**
 * Homepage presenter.
 */
class HomepagePresenter extends BasePresenter
{
    /** @var Models\User */
    private $userModel;


    /**
     * Inject all models that are expected to be used in most of BasePresenter's ancestors
     * @param Models\User
     */
    public function injectUser(ProjectManagement\User $userModel)
    {
        $this->userModel = $userModel;
    }


    /**
     *
     */
    public function renderDefault()
    {
        $this->template->users = $this->userModel->fetch();
    }

}

BasePresenter je zatím prázdný.

Editoval EdWood (21. 3. 2013 1:58)

Tomáš Votruba
Moderator | 1114
+
0
-

Ahoj, ještě by to chtělo laděnku nebo aspoň hlášenou chybu.
Případně také zkus Nette 2.0.5 zmiňované v návodu, zda to není problém ve verzi.

EdWood
Člen | 16
+
0
-

Schmutzka napsal(a):

Ahoj, ještě by to chtělo laděnku nebo aspoň hlášenou chybu.
Případně také zkus Nette 2.0.5 zmiňované v návodu, zda to není problém ve verzi.

Call to undefined method ProjectManagement\User::fetch().

uestla
Backer | 799
+
0
-

Přeložím ti to: Voláš metodu ProjectManagement\User::fetch(), kterážto neexistuje.

Šaman
Člen | 2666
+
0
-

Zkus tohle. A nedoporučuji dělat fetch() už v modelu, protože pak nemůžeš výsledek dál iterovat, pokud by se ti vrátilo víc řádků. V tomto případě ti to nevrací $users ale jen $user.

<?php
public function renderDefault()
{
    $this->template->users = $this->userModel->getByName('jmeno');
}
?>

A trochu offtopic: doporučuji ti konkrétnější názvy tříd. Ta třída Base a User jsou dost nejasný. BaseRepository, UserRepository by mi přišlo výstižnější (User je většinou entita reprezentující konkrétního uživatele).

A poslední připomínka – nechceš radši zkusit pracovat s Nette\Database? Z NotORMu vychází je má podobný přístup k datům, ale je nativně v Nette a vyvíjí se. Jestli máš nějaký konkrétní důvod proč NotORM pak ok, ale jestli nemáš, jdi do NDatabase.

Editoval Šaman (21. 3. 2013 4:04)

EdWood
Člen | 16
+
0
-

Díky za připomínky,
tohle jsem taky zkoušel, ale to mi pak vrací: Trying to get property of non-object. K těm třídám, normálně je takhle píšu, ale jelikož mi to furt nejelo, tak jsem to vzal pak přímo z toho návodu. Pokud se to tak teda dělat nemá, tak by bylo dobrý to přepsat i tam, ať to nás začátečníky nemate. Máš pravdu, vrátím se k Nette\Database, tohle jsem si chtěl jen vyzkoušet, protože se to docela chválilo :)

Šaman
Člen | 2666
+
0
-

A vrátilo ti to z db nějaký záznam podle toho jména? Jestli ne, tak logicky nemáš objekt. A pokud ano, co s ním dál dělás v šabloně?

Máš pravdu, v tom článku tak pojmenované jsou. Problém je, že na Planette jsou ukázky a návody širokého spektra lidí. Není to dokumentace, teoreticky si tam může každý napsat co chce, pokud nepíše nesmysly. Tomáš Votruba má buď jiný názor na pojmenování tříd, nebo se snažil o co nejjednodušší příklad bez vysvětlování co je Repository. Taky mohl použít názvy tříd A, B, C.
To lepší pojmenování nemá vliv na funkčnost, jen ti to doporučuji, ve větším projektu je zmatečné mít X tříd Base.php.

Praktickou ukázku, jak DI (o čemž byl ten článek – ne o práci s databázi), tak práci s NDatabase najdeš v QuickStartu. Zkus se inspirovat tam. Tohle nebyl ucelený příklad na model, jen na DI.