Dotaz na databázy v latte
- Miky0007
- Člen | 73
Poradí prosím někdo jak lze v latte šabloně položit dotaz na konkrétní sloupec v tabulce podle id?
Mám to asi takhle, ale to nefunguje:
{foreach $database->table('vzkazy')->order('datum DESC') as $vzkaz}
<table class="tabulka">
<tr><td class="malePismo"></td><td class="vzkaz">{$vzkaz->predmet}<td></tr>
<tr><td class="malePismo">{$database->table('uzivatele')->where('id',$vzkaz->uziv_id)->select('nick')}<br/>
{$vzkaz->datum |date:'%d.%m.%Y'}</td><td class="vzkaz">{$vzkaz->vzkaz}<td></tr>
<tr> <td n:if="$user->isAllowed([vzkaz, $user->id, $vzkaz], edit)" class="vzkaz"><a n:href="edit $vzkaz->id">EDIT</a></td><td n:if="$user->isAllowed([vzkaz, $user->id, $vzkaz], edit)" class="vzkaz"><a n:href="Homepage:smaz $vzkaz->id">SMAZ</a></td></tr>
</table>
{/foreach}
</br>
Jde mně o tento dotaz Vzkazy to normálně vypíše..
$database->table('uzivatele')->where('id',$vzkaz->uziv_id)->select('nick')
id int(11) Auto Increment
nick varchar(50)
email varchar(50)
poznamka varchar(200) NULL
registrace datetime NULL
naposledyOnline datetime NULL
heslo varchar(100)
- ViPEr*CZ*
- Člen | 817
Doporučuji nastudovat quickstart a modely a pak v dokumentaci juknout i na použití NDB. Každopádně takto ošklivě to samozřejmě musí fungovat taky, ale toto:
{$database->table('uzivatele')->where('id',$vzkaz->uziv_id)->select('nick')}
vrací objekt, takže to ten nick nevypíše… takhle už by ho to vypsat mělo:
{$database->table('uzivatele')->get($vzkaz->uziv_id)->nick}
- ViPEr*CZ*
- Člen | 817
Miky0007 napsal(a):
ok díky a co je na tom prosím ošklivýho?
To poznáš až se mrkneš na ten quickstart… v šabloně (view vrstvě) by jsi neměl takhle pracovat s databází. A taky předpokládám, že tabulka vzkazy je propojená s tabulkou uzivatele přes sloupec uziv_id, tak že to použití $database->table(‚uzivatele‘)->get($vzkaz->uziv_id)->nick je zbytečně složité a dalo by se využít toho spojení $vzkaz->uzivatele->nick což je podstatně jednodušší zápis.
- Miky0007
- Člen | 73
Máš pravdu už nepředávám view spojení na databázi, ale jen tabulku,
kterou vytáhnu v modelu…
Model:
function getVzkaz()
{
return $this->database->table('vzkazy');
}
Presenter:
$this->template->vzkazy = $this->context
->vzkazModel->vzkaz->page($page, 5);
View:
{default $page => 1}
{foreach $vzkazy->order('datum DESC') as $vzkaz}
<table class="tabulka">
<tr><td class="malePismo"></td><td class="vzkaz">{$vzkaz->predmet}<td></tr>
<tr><td class="malePismo">{$vzkaz->uzivatele->nick}<br/>
{$vzkaz->datum |date:'%d.%m.%Y'}</td><td class="vzkaz">{$vzkaz->vzkaz}<td></tr>
<tr> <td n:if="$user->isAllowed([vzkaz, $user->id, $vzkaz], edit)" class="vzkaz"><a n:href="edit $vzkaz->id">EDIT</a></td><td n:if="$user->isAllowed([vzkaz, $user->id, $vzkaz], edit)" class="vzkaz"><a n:href="Homepage:smaz $vzkaz->id">SMAZ</a></td></tr>
</table>
{/foreach}
Akorát mně to zatím píše, že nebyla nalezena reference…
- Miky0007
- Člen | 73
Tabulka vzkazy
Sloupec Typ Komentář
id int(11) Auto Increment
vzkaz varchar(400)
datum datetime
predmet varchar(80)
uziv_id int(11)
Indexy
PRIMARY id
INDEX uziv_id
Pozměnit indexy
Cizí klíče
Zdroj Cíl Při smazání Při změně
uziv_id uzivatele(id) NO ACTION NO ACTION Změnit
Přidat cizí klíč
Triggery
Přidat trigger
Tabulka uzivatele
Sloupec Typ Komentář
id int(11) Auto Increment
nick varchar(50)
email varchar(50)
poznamka varchar(200) NULL
registrace datetime NULL
naposledyOnline datetime NULL
heslo varchar(100)
Indexy
PRIMARY id
Pozměnit indexy
Cizí klíče
Přidat cizí klíč
Triggery
Přidat trigger
- Miky0007
- Člen | 73
Ano přesně jak říkáš..Cache jsem smazal a dělá to furt to samí a po
dumpu to vypsalo asi toto:
$vzkaz->ref(‚uzivatele‘, ‚uziv_id‘)
Nette\Database\Table\ActiveRow(3) ▼ {
table private ⇒ Nette\Database\Table\Selection(16) ▼ {
connection protected ⇒ Nette\Database\Connection(6) ▼ {
dsn private ⇒ „mysql:host=localhost;dbname=satec“ (33)
driver private ⇒ Nette\Database\Drivers\MySqlDriver(1) { … }
preprocessor private ⇒ Nette\Database\SqlPreprocessor(6) { … }
databaseReflection private ⇒ Nette\Database\Reflection\DiscoveredReflection(4)
{ … }
cache private ⇒ Nette\Caching\Cache(4) { … }
onQuery ⇒ array(1) [ … ]
}
sqlBuilder protected ⇒ Nette\Database\Table\SqlBuilder(12) ►
name protected ⇒ „uzivatele“ (9)
primary protected ⇒ „id“ (2)
primarySequence protected ⇒ FALSE
rows protected ⇒ array(1) ▼ {
1 ⇒ Nette\Database\Table\ActiveRow(3) { RECURSION }
}
data protected ⇒ array(1) ▼ {
1 ⇒ Nette\Database\Table\ActiveRow(3) { RECURSION }
}
referenced protected ⇒ array(0)
referencing protected ⇒ array(0)
referencingPrototype protected ⇒ array(0)
aggregation protected ⇒ array(0)
accessed protected ⇒ array(1) ▼ {
id ⇒ TRUE
}
prevAccessed protected ⇒ NULL
observeCache protected ⇒ TRUE
checkReferenced protected ⇒ FALSE
keys protected ⇒ array(0)
}
data private ⇒ array(7) ►
modified private ⇒ array(0)
}
- ViPEr*CZ*
- Člen | 817
Miky0007 napsal(a):
Tak to normálně funguje…Díky moc chlape
Ok. V podstatě to dělá to samé jako ten původní zápis
{$vzkaz->uzivatele->nick} jen přes tu metodu ref jsi řekl v druhým
parametru přes jaký sloupec se má podívat do té tabulky uzivatele.
Proč ti nefunguje ten zkrácený zápis přesně nevím… musel bych asi
někde zkoušet, takhle na první pohled to nevidím. Pokud to je verze před
2.0.6, tak tam taky záleželo na konvenci zápisu jména cizýho klíče. Jinak
pak Reflexe neví přes jaký sloupec se podívat.
- ViPEr*CZ*
- Člen | 817
Miky0007 napsal(a):
Každopádně děkuju tohle funguje a snad to není taková čunárna jako předtím :-)
No oddělil jsi to do modelu což je správně, ten zápis přes ref je taky
správně (jen je složitější, ale správně). Takže tyto dva body co
řeší toto téma jsou určitě pořešený.
Můžeš ještě vykoumat proč nefunguje ten zkrácenej zápis, aby to bylo
ještě lepší ;-)
- Miky0007
- Člen | 73
Jo já to určitě prokoumu…Ale až na to budu mít víc času..ted se chci
s tou aplikací posunout víc dopředu…Ale chápu to správně, že když
pracuju s více tabulkama musím v presenteru z modelu předat všechny
tabulky že? Jak by vypadal prosím dotaz kdybych chtěl vypsat třeba ze třech
tabulek všechny uživatele a jejich oprávnění? Pokud by tabulky vypadali
třeba takhle:
Tabulka Uzivatele
Id
Jmeno
Email
Tabulka Role
Id
Opravneni
Tabulka Uziv_Opravneni
uzivatel_id – cizí klíč z tabulky uzivatele
uzivatelska_role_id – cizí klíč z tabulky role
Jde to vůbec? Když každej uživatel může mít více oprávnění…
- ViPEr*CZ*
- Člen | 817
Takhle se to nedělá… stačí na to dvě tabulky propojené vazbou 1:N.
user
userID
name
email
role
roleID
name
userID (cizí klíč na uživatele)
V tuto chvíli může uživatel mít více rolí a tudíž jeden uživatel může mít více řádků v tabulce role. Pak to mohu zjistit takto:
$users = $database->table("user");
Tímto si získáme všechny uživatele. Nebo lépe řečeno objekt Selection, nad kterým lze iterovat. V praxi:
foreach($users as $user) {
$user->nick;
}
a pokud chci role k danému uživateli mohu použít metodu related:
foreach($users as $user) {
$user->nick;
$roles = $users->related("role", "userID");
foreach ($roles as role) {
$role->name;
}
}
A nebo to jde pak obráceně jak už jsem ukazoval (získat si role například podle name a k danému řádku s rolí si mohu přes klíč získat uživatele).
- jiri.pudil
- Nette Blogger | 1032
Takhle se to nedělá… stačí na to dvě tabulky propojené vazbou 1:N. (…) V tuto chvíli může uživatel mít více rolí a tudíž jeden uživatel může mít více řádků v tabulce role.
V tvém návrhu ale nemůže mít více uživatelů stejnou roli; tedy ne bez duplicit v tabulce „role“. Řekl bych, že je vazba M:N zcela na místě.
Editoval jiri.pudil (27. 12. 2012 17:57)
- Miky0007
- Člen | 73
Já to možná napsal blbě…Ono jeden uživatel může mít více rolí..Ale jedna role má samozřejmě více uživatelů..Takže mně příjde že tři tabulky jsou na místě…Teda aspoň nás to tak kdysi učili na škole :-) S těmi třema tabulkama to nějak jde? Ted mě tak napadlo, že tabulky propojuju až ve view..Nebylo by možná lepší to udělat už v modelu…nákou funkcí?
- ViPEr*CZ*
- Člen | 817
jiri.pudil napsal(a):
Takhle se to nedělá… stačí na to dvě tabulky propojené vazbou 1:N. (…) V tuto chvíli může uživatel mít více rolí a tudíž jeden uživatel může mít více řádků v tabulce role.
V tvém návrhu ale nemůže mít více uživatelů stejnou roli; tedy ne bez duplicit v tabulce „role“. Řekl bych, že je vazba M:N zcela na místě.
Máš pravdu, moje chyba… takhle to bude určitě lepší… omlouvám se
;-)
Asi jsem se nechal chytit na této větě: „Jde to vůbec? Když každej
uživatel může mít více oprávnění…“ a už jsem ani
nepřemýšlel moc dál a udělal jsem ukázku jak pracují vazby. :-D
- ViPEr*CZ*
- Člen | 817
Miky0007 napsal(a):
Já to možná napsal blbě…Ono jeden uživatel může mít více rolí..Ale jedna role má samozřejmě více uživatelů..Takže mně příjde že tři tabulky jsou na místě…Teda aspoň nás to tak kdysi učili na škole :-) S těmi třema tabulkama to nějak jde? Ted mě tak napadlo, že tabulky propojuju až ve view..Nebylo by možná lepší to udělat už v modelu…nákou funkcí?
Přes ty tři tabulky se to dělá úplně stejně jak jsem už popisoval se
dvěma ;-)
V šabloně si šáhnout přes reference na druhou tabulku je ok ;-)