Cizí klíče nefungují (konvence dodržuji)
- kedrigern
- Člen | 102
Verze Nette: 2.0.3-PHP5.3
Vytvořím si DB a příslušné tabulky:
SET NAMES utf8;
SET foreign_key_checks = 0;
CREATE DATABASE IF NOT EXISTS `nette` CHARACTER SET = utf8;
/* Přesunu se do právě vytvořené DB nette */
USE `nette`;
/* Vytvoř uživatele nette s heslem nette */
CREATE USER 'nette'@'%' IDENTIFIED BY 'nette';
/* Uživatel nette dostane všechny práva pro DB nette */
GRANT ALL ON `nette`.* TO 'nette' ;
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`nick` varchar(10) NOT NULL,
`password` char(128) NOT NULL,
`name` varchar(10),
`surname` varchar(15),
`datum` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `nick` (`nick`)
) ENGINE=InnoDB;
CREATE TABLE `category` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`category_id` int(10) unsigned NOT NULL,
`title` varchar(12) NOT NULL,
`description` varchar(150),
PRIMARY KEY (`id`),
UNIQUE KEY `title` (`title`),
INDEX `fk_category2` (`category_id`),
CONSTRAINT `fk_category2` FOREIGN KEY (`category_id`) REFERENCES `category` (`id`)
) ENGINE=InnoDB;
CREATE TABLE `post` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`users_id` int(10) unsigned NOT NULL,
`title` varchar(20),
`datum` datetime NOT NULL,
`text` varchar(150),
`category_id` int(10) unsigned NOT NULL DEFAULT 1,
PRIMARY KEY (`id`),
INDEX `fk_users` (`users_id`),
INDEX `fk_category` (`category_id`),
CONSTRAINT `fk_users` FOREIGN KEY (`users_id`) REFERENCES `users` (`id`),
CONSTRAINT `fk_category` FOREIGN KEY (`category_id`) REFERENCES `category` (`id`)
) ENGINE=InnoDB;
FLUSH PRIVILEGES;
V Admineru vidím správně schéma i cizí klíče.
Tabulka sama se vypíše v pořádku. Nicméně cizí klíč již ne, např:
{var $title = "Posts"}
{block content}
{if count($posts) > 0}
{foreach $posts as $post}
<h2>{$post->title}</h2>
<span class="author">Autor: {$post->users_id->nick}</span>
<span class="category">Kategorie: {$post->category_id}</span>
<span class="date">Vytvořeno: {$post->datum}</span><br />
{!$post->text}
{/foreach}
{else}
<p> Nejsou žádné příspěvky</p>
{/if}
Vyhodí (Laďenka):
Notice
Trying to get property of non-object
Jsou ještě nějaká další pravidla pro to, aby mi propojení tabulek fungovalo?
Už jsem zjistil, že potřebuji ENGINE=InnoDB a cizí klíč pojmenovat „tabulka_id“, kde tabulka je jméno tabulky na kterou se odkazuji.
- Prošel jsem tyto vlákna
- https://forum.nette.org/…tte-database
- https://forum.nette.org/…edreflection
A nepomohlo to.
Připojuji se k DB dle Quickstartu (factory, v modelu třída pro každou tabulku).
Editoval kedrigern (20. 5. 2012 2:25)
- duke
- Člen | 650
Předpokládám, že používáš DiscoveredReflection.
Myslím, že když místo {$post->users_id->nick}
použiješ
{$post->user->nick}
, že to pojede. Mělo by fungovat i
{$post->users->nick}
. Zápis
{$post->users_id}
je nejspíš rezervován pro přístup
k hodnotě toho sloupce users_id, i když v jednom z odkazovaných
příspěvků tam Hrach uvádí, že i to by mělo fungovat… (ale to je
5 měsíců starý komentář, takže může být již neaktuální)
Editoval duke (20. 5. 2012 3:06)
- kedrigern
- Člen | 102
duke> No právěže jsem z toho dost zmaten. Ne že bych nehledal, ale spíš vyznat se v tom, co je platné, není rozbité a podobně není úplně triviální. Proto už se ani neptám na chybu, al na ty podmínky (ono najít je všechny pohromadě také není lehké).
Už to funguje! Tyto tři zápisy ozkoušeny:
<span class="author">Autor: {$post->ref('users_id')->nick}</span>
<span class="author">Autor: {$post->user->nick}</span>
<span class="author">Autor: {$post->users->nick}</span>
Nesmí se tam přímo uvádět název té reference.
Děkuji moc, jak se Nette teprve učím, tak občas přehlížím detaily, protože jsem si prostě nejistý, kde co může být špatně.
PS: značí se tu nějak vyřešená vlákna?
Editoval kedrigern (20. 5. 2012 13:09)
- jtousek
- Člen | 951
ViPErCZ napsal(a):
Používal bych asi toto $post->users->nick kdy je vidět, že se ta tabulka jmenuje users a ne user, jak by se mohlo zdát z druhého zápisu.
Já bych zase tu tabulku pojmenoval user.
EDIT: Tabulku kategorií má také pojmenovanou category a ne categories. Konvence jsou konvence, někdo používá jednotné číslo, někdo množné. Moje preference je používat jednotné. Ale rozhodně není dobrý nápad to míchat.
Editoval jtousek (20. 5. 2012 13:51)
- ViPEr*CZ*
- Člen | 817
jtousek napsal(a):
ViPErCZ napsal(a):
Používal bych asi toto $post->users->nick kdy je vidět, že se ta tabulka jmenuje users a ne user, jak by se mohlo zdát z druhého zápisu.
Já bych zase tu tabulku pojmenoval user.
EDIT: Tabulku kategorií má také pojmenovanou category a ne categories. Konvence jsou konvence, někdo používá jednotné číslo, někdo množné. Moje preference je používat jednotné. Ale rozhodně není dobrý nápad to míchat.
Naprosto souhlasím. Také používám jednotná čísla. Ale je to prakticky jedno, ať si dotyčný vybere. Jen jak jsi psal… míchat to se nevyplácí. ;-)
- kedrigern
- Člen | 102
Jo, jenže když se použije jednotné číslo, tak dostanu:
Nette\DI\ServiceCreationException
It is not allowed to use service and factory with the same name 'user'.
A teď zkoumám, kde se přesně a jak definuje ten defaultní servise user (pracuji nad sandboxem).
Proto jsem to zatím nepoužíval, protože jsem si nejdřív chtěl vyzkoušet základy.
- kedrigern
- Člen | 102
Jo já to vidím, jen ještě nevím jak to použít.
A jak vyřešit konflikt jmen. Nejednodušší je asi nedefinovat továrnu pro user, avšak ještě nevím jak si je pak třeba vypsat ad hoc.
Prostě je toho pro mě dost nového.
Edit: Je někde popis jak používat Services? Továrnu jsem pochopil z quickstartu. Service je „jakási perzistentní továrna“, avšak nevím co třeba ta předdefinovaná umí.
Edit2: Tak jsem továrnu přejmenoval na „userfactory“, protože servis jsem neuměl využít stejně jako továrnu (například, když chci vypsat všechny uživatele). Kdybyste mi někdo poradil, jak používat servis, tak budu rád.
Editoval kedrigern (20. 5. 2012 21:15)