Jak napsat model rozšiřující Nette\Database (Selection?)
- kahi
- Člen | 32
Upravuji aplikaci postavenou na Nette\Database, podobně jako v příkladu:
{foreach $database->table('book')->order('title')->limit(5) as $book}
<h2>{$book->title} ({$book->author->name})</h2>
{foreach $book->related('book_tag') as $book_tag}
{$book_tag->tag->name}{sep}, {/sep}
{/foreach}
{/foreach}
Nicméně rád bych to zpřehlednil a některé složitější konstrukce dostal z šablony někam jinam (předpokládám do vlastního modelu) a pro přístup k těmto méně banálním properties přistupoval cca takto:
$book->mainCategory->title
místo něčeho jako
$book->related('tags')->where('type = ?', '123')->orderBy('priority')->fetch()->title
Nemám představu jak takové rozšíření implementovat. Díky!
Editoval kahi (3. 10. 2012 15:38)
- jansfabik
- Člen | 193
Zkus se mrknout na https://github.com/fabik/database. Takhle nějak bys to mohl použít:
models/Book.php
<?php
namespace Web;
use Database\ActiveRow;
class Book extends ActiveRow
{
public function getTags()
{
return $this->related('tags');
}
/** @return Tag */
public function getMainCategory()
{
return $this->getTags()->where('type = ?', '123')->orderBy('priority')->fetch();
}
}
models/Books.php
<?php
namespace Web;
use Database\Table;
class Books extends Table
{
protected $name = 'books';
public function listAll()
{
return $this->findAll()->order('title');
}
public function listTopFive()
{
return $this->listAll()->limit(5);
}
}
models/Tag.php
<?php
namespace Web;
use Database\ActiveRow;
class Tag extends ActiveRow
{
}
models/Tags.php
<?php
namespace Web;
use Database\Table;
class Tags extends Table
{
protected $name = 'tags';
}
config.neon
services:
# database
modelManager: Database\ModelManager
rowFactory: Database\RowFactory({
books: Web\Book # tohle namapuje řádky tabulky books na entity Web\Book
tags: Web\Tag
})
# models
books: Web\Books
tags: Web\Tags
v presenteru pak:
<?php
namespace Web;
class BooksPresenter extends BasePresenter
{
/** @var Web\Books */
protected $books;
public function inject(Books $books)
{
$this->books = $books;
}
public function renderDefault()
{
$this->template->books = $this->books->listTopFive();
}
}
- kahi
- Člen | 32
@jansfabik: děkuji, vypadá to jako přesně to, co potřebuji. Bohužel to dopadne takto: http://cl.ly/…1M1t1e314412 (Nahrál jsem Database do libs a přidal ten úryvek do configu… Netuším, co tomu chybí.) :(
- David Ďurika
- Člen | 328
ukaz config.neon mas tam nieco zle nastavene, pravdepodobne pripojenie
k DB
mal by si tam mat nieco taketo:
<?php
nette:
database:
default:
dsn: '%database.driver%:unix_socket=%database.socket%;host=%database.host%;dbname=%database.dbname%'
user: %database.user%
password: %database.password%
# reflection: conventional
services:
database: @nette.database.default
?>
- ViPEr*CZ*
- Člen | 817
public function getTags()
{
return $this->related('tags');
}
/** @return Tag */
public function getMainCategory()
{
return $this->getTags()->where('type = ?', '123')->orderBy('priority')->fetch();
}
Toto $this->getTags() nevrací vždy objekt, pokud to nenajde žádný odpovídající řádek… to není úplně ok a může to končit chybou, když se na to rovnou napojí where.
- jansfabik
- Člen | 193
ViPEr*CZ Opravdu? Díval jsem se do API, volá se tam funkce Selection::getReferencingTable() a ta vrací objekt vždy.
Nebo ti to někde hází chybu? Například by mohlo vadit, že
nepoužíváš InnoDB, ale třeba MyISAM. Pak je potřeba používat
$this->related('tags', 'tag_id')
, protože MyISAM nemá podporu
pro klíče.
Editoval jansfabik (4. 10. 2012 22:31)
- David Ďurika
- Člen | 328
mne vyhadzuje niekedy ‚Invalid argument supplied for foreach()‘ a to v nasledovnom kode:
<?php
$selection = $row->related('table');
dump($selection);
foreach($selectin as $value) { // to to hodi chybu
}
?>
ked stranku refreshnem tak to uz zbehne OK!
dump toho $selection je stale Nette\Database\Table\GroupedSelection
nevies co s tym moze byt?
- jansfabik
- Člen | 193
Vyrobil jsem si nový projekt ze sandboxu a opravdu narazil na bug v masteru.
$articles = $connection->table('articles');
foreach ($articles as $article) {
dump($article);
//$author = $article->ref('users', 'author_id');
//dump($author);
}
Když při prvním requestu nejprve načtu jenom článek a při druhém
requestu odkomentuju autora, vyhazuje ten druhý dump FALSE
.
Když promažu cache, tak to opět funguje.
Editoval jansfabik (30. 10. 2012 16:04)