Spojení 2 tabulek pomoci Nette Database
- wicked
- Člen | 290
Zdravím přátelé,
Prosím Vás o radu, mám 2 tabulky s daty zakazniku
1. zakaznici
Pole Typ Nulový Výchozí Komentáře
id int(10) Ne
firma varchar(255) Ano NULL
ic varchar(30) Ano NULL
dic varchar(30) Ano NULL
web varchar(100) Ano NULL
datum_ulozeni datetime Ano NULL
a 2. zakaznici_kontakty
Pole Typ Nulový Výchozí Odkazuje na Komentáře
id int(10) Ne
zakaznici_id int(10) Ne zakaznici → id
titul_pred varchar(70) Ano NULL
jmeno varchar(70) Ano NULL
prijmeni varchar(70) Ano NULL
titul_po varchar(70) Ano NULL
ulice varchar(255) Ano NULL
mesto varchar(70) Ano NULL
psc varchar(30) Ano NULL
telefon varchar(50) Ano NULL
mail varchar(80) Ano NULL
datum_ulozeni datetime Ano NULL
pozn varchar(255) Ano NULL
Obě tabulky jsou spolu spojeny cizím klíčem zakaznici_kontakty.zakaznici_id který směruje na zakaznici.id
Mám v šabloně akci na vytáhnutí dat z obou tabulek a následné plnění do formuláře.
public function actionUpravit($id) {
// Najdeme zaznam
$zakaznici = $this->zakaznici->findAll()->where('id', $id);
// Pokud neni nalezen, presmeruji a vypisu zpravu
if (!$zakaznici->count()) {
$this->flashMessage("Zákazník nenalezen!", "alert alert-success");
$this->redirect("default");
}
// Nacteme data
$zakaznici = $zakaznici->fetch();
dump($zakaznici);
// Nastavime defaultni hodnoty do formulare a nahradime button
$this["zakaznikForm"]->setDefaults($zakaznici);
$this["zakaznikForm"]['send']->caption = "Uložit";
// Dostaname data do sablony
$this->template->zakaznici = $zakaznici;
}
Toto mi správně dostane všechny údaje z tabulky zakaznici a dosadí je
Když zadám
$zakaznici = $this->zakaznici->findAll()->where(':zakaznici_kontakty.zakaznici_id', $id);
Udělá to dotaz
SELECT `zakaznici`.*
FROM `zakaznici`
LEFT JOIN `zakaznici_kontakty` ON `zakaznici`.`id` = `zakaznici_kontakty`.`zakaznici_id`
WHERE (`zakaznici_kontakty`.`zakaznici_id` = '172')
Ale data nevypíše, respektivě vypíše pouze z tabulky zakaznici.
Chci se zeptat, co přehlížím?
Daří se mě vypsat buď dat ze zakaznici nebo zakaznici_kontakty ale aby se to
spojilo a vypsalo to oboji najednou, to mě už nejde …
Děkuji
Editoval wicked (25. 8. 2014 10:38)
- David Matějka
- Moderator | 6445
https://doc.nette.org/…ase/explorer
Hlavní myšlenkou je načítání dat pouze z jedné tabulky a tak, aby se tyto dotazy pokládaly jen jednou. Data jsou načtena do ActiveRow instancí. Data z jiných tabulek připojených vazbami jsou načteny samostatnými požadavky – o to se stará samotná vrstva Database\Table.
pouzij related
- wicked
- Člen | 290
Ano, related používám v tabulce, která mi vypisuje všechna data
<tbody>
<tr n:foreach="$zakaznici as $z">
<td>{$z->id}</td>
<td>{if $user->identity->data["zakaznici_editace"] == "1"}<a n:href="upravit, $z->id">{else}<a n:href="zobrazit, $z->id" target="_blank">{/if}{$z->firma}</a></td>
<td>{$z->ic}</td>
<td>{$z->dic}</td>
{foreach $z->related('zakaznici_kontakty') as $z}
<td>{$z->jmeno}</td>
<td>{$z->prijmeni}</td>
<td>{$z->mesto}</td>
<td>{$z->telefon}</td>
<td>{$z->mail}</td>
<td>{$z->pozn}</td>
{/foreach}
{if $user->identity->data["zakaznici_prohlizeni"] == "1"}<td align="center"><a n:href="Projekty:vlozit, $z->id"><img src="{$basePath}/pic/vloz_zakaznika.png" alt="Vložit zákazníka do projektu" title="Vložit zákazníka do projektu"></a></td>{else}<td>-</td>{/if}
{if $user->identity->data["zakaznici_editace"] == "1"}<td align="center"><a n:href="upravit, $z->id"><img src="{$basePath}/pic/edit.gif" alt="Editovat uživatele" title="Editovat uživatele"></a></td>{else}<td>-</td>{/if}
{if $user->identity->data["zakaznici_prohlizeni"] == "1"}<td align="center"><a n:href="zobrazit, $z->id" target="_blank"><img src="{$basePath}/pic/detail.png" alt="Detail zákazníka" title="Detail zákazníka"></a></td>{else}<td>-</td>{/if}
{if $user->identity->data["zakaznici_editace"] == "1"}<td align="center"><a n:href="smazat!, $z->id" onClick="return dotaz();"><img src="{$basePath}/pic/delete.gif" alt="Smazat uživatele" title="Smazat uživatele"></a></td>{else}<td>-</td>{/if}
</tr>
</tbody>
Napadlo mě použít relater, ale jak to udělat, aby mě to naplnilo formulář správnými daty? Proto to řeším takto v presenteru
- David Matějka
- Moderator | 6445
wtf? to jako kdyz bude mit zakazik vice zaznamu v te druhe tabulce, tak do
bude pridavat sloupce?
nebo mas jen spatne navrzenou databazi?
jinak related pro vytazeni tech kontaktu muzes pouzit i v presenteru.
Editoval matej21 (25. 8. 2014 18:43)
- wicked
- Člen | 290
Related jsem v presenteru zkoušel použít, ale asi špatně…
Ano zákazník může mít více řádků v tabulce zákazníci_kontakty které se v default všechny vypisou.
Po kliknutí na Edit chci načíst data k danému id z obou tabulek a vypsat do formu pro editaci.
Nevím jak jinak navrhnout db, myslel jsem, že takto je ok.
Editoval wicked (25. 8. 2014 18:55)
- David Matějka
- Moderator | 6445
ok, v tom pripade je struktura asi ok, jen to vypisovani do tabulky hodne debilni :)
v presenteru normalne pomoci
foreach($z->related('zakaznici_kontakty') as $kontakt)..
projdes
kontakty a dosadis je do formulare (asi replicator pouzivas, ne?)
- wicked
- Člen | 290
matej21 napsal(a):
ok, v tom pripade je struktura asi ok, jen to vypisovani do tabulky hodne debilni :)
v presenteru normalne pomoci
foreach($z->related('zakaznici_kontakty') as $kontakt)..
projdes kontakty a dosadis je do formulare (asi replicator pouzivas, ne?)
Ne, zatím jsem replicator ještě nepoužil/nepoužíval…
V presenteru ale $z musím nahradit za $zakaznici, ne?
Jak myslíš dosazovani do tabulky debilní? Já myslel, že takto se to má používat…
- David Matějka
- Moderator | 6445
mam na mysli tu html tabulky, konkretne kod
{foreach $z->related('zakaznici_kontakty') as $z}
<td>{$z->jmeno}</td>
<td>{$z->prijmeni}</td>
<td>{$z->mesto}</td>
<td>{$z->telefon}</td>
<td>{$z->mail}</td>
<td>{$z->pozn}</td>
{/foreach}
ze se budou pridavat sloupce dle poctu zaznamu v te tabulce..
- wicked
- Člen | 290
Jo to musím ještě dořešit, přidávají se blbě sloupce, má se přidávat komplet záznam = řádek…
Jinak related v presenteru projít klasický foreach a pak setDefaultsna formulář? Když kouknes na ten můj action kde načítám data a nastavují je do editu, jak by jsi to zakomponovat?
Jinak tu html tabulku musím dopravit, takhle nefunguje dobře.
- David Matějka
- Moderator | 6445
no nevim, jak vypada tvuj form, tak ti neporadim. ale proste projdes ve foreach-y a nastavis hodnoty na jednotlive containery (v replicatoru nebo jak to mas reseny)
- wicked
- Člen | 290
matej21 napsal(a):
no nevim, jak vypada tvuj form, tak ti neporadim. ale proste projdes ve foreach-y a nastavis hodnoty na jednotlive containery (v replicatoru nebo jak to mas reseny)
Ten form není ničím zvláštní …
// Formular na pridani zakaznika
public function createComponentZakaznikForm() {
$form = new Form();
// Nastavime inputy
$form->addText('firma', 'Firma')
->setAttribute('class', 'form-control')
->setRequired('Firma musí být vyplněna!');
$form->addText('ic', 'IČ')
->setAttribute('class', 'form-control');
$form->addText('dic', 'DIČ')
->setAttribute('class', 'form-control');
$form->addText('titul_pred', 'Titlu před jménem')
->setAttribute('class', 'form-control');
$form->addText('jmeno', 'Jméno')
->setRequired('Jméno musí být vyplněno!')
->setAttribute('class', 'form-control');
$form->addText('prijmeni', 'Přijmení')
->setRequired('Přijmení musí být vyplněno!')
->setAttribute('class', 'form-control');
$form->addText('titul_po', 'Titul za jménem')
->setAttribute('class', 'form-control');
$form->addText('ulice', 'Ulice')
->setRequired('Ulice musí být vyplněna!')
->setAttribute('class', 'form-control');
$form->addText('mesto', 'Město')
->setRequired('Město musí být vyplněno!')
->setAttribute('class', 'form-control');
$form->addText('psc', 'PČS')
->setRequired('PČS musí být vyplněno!')
->setAttribute('class', 'form-control');
$form->addText('telefon', 'Telefon')
->setAttribute('class', 'form-control');
$form->addText('mail', 'Email')
->setAttribute('class', 'form-control');
$form->addText('web', 'Web')
->setAttribute('class', 'form-control');
$form->addText('pozn', 'Poznámka')
->setAttribute('class', 'form-control');
// Odesilaci tlacitko
$form->addSubmit('send', 'Přidat zákazníka')
->getControlPrototype()
->class('btn btn-info');
// Zavolame metodu usersFormSucceeded()po uspechu
$form->onSuccess[] = $this->zakaznikFormSucceeded;
// Set Twitter Bootstrap render
$form->setRenderer(new BootstrapRenderer());
return $form;
}
- David Matějka
- Moderator | 6445
no prave ze by mel byt zvlastni – kdyz rikas, ze zakaznik muze mit vice kontaktu – takhle bys mohl editovat pouze jeden… koukni na replicator https://componette.org/search/?…
Editoval matej21 (25. 8. 2014 23:39)
- David Matějka
- Moderator | 6445
ty v te tabulce nevypisujes radky pro jednotlive kontakty, ale pro
jednotlive zakazniky..
jak chces, aby se to chovalo, kdyz bude mit zakaznik 2 kontakty?
- wicked
- Člen | 290
No chtěl bych, aby se přidal druhý řádek s info o zákazníkovi a kontaktu
proste zakaznik + kontakt je jeden radek, pod nim bude druhy kde bude zase zakaznik a další kontakt
kdyz kliknu na edit, edituji vesker info jak o zakaznikovi (firma, ic, dic, web) tak o kontaktu (jmeno, prijmeni, tel)
- David Matějka
- Moderator | 6445
tak to bude lepsi, kdyz jako „zaklad“ nebudes brat tu tabulku zakaznici, ale tabulku zakaznici_kontakty – tedy vyberes z ni data, vypises do tabulky, pomoci ref() ziskas data zakaznika, pri odkazovani na editaci pouzijes id kontaktu a ne id zakaznika…
- wicked
- Člen | 290
Když provedu
public function actionUpravit($id) {
$zakaznici = $this->zakaznici->findAll()->where('zakaznici.id', $id)->fetch();
foreach($zakaznici->related('zakaznici_kontakty') as $zakaznici)
dump($zakaznici);
$this["zakaznikForm"]->setDefaults($zakaznici);
$this["zakaznikForm"]['send']->caption = "Uložit";
// Dostaname data do sablony
$this->template->zakaznici = $zakaznici;
}
Položí to dotazy
SELECT *
FROM `zakaznici`
WHERE (`zakaznici`.`id` = '83')
a
SELECT *
FROM `zakaznici_kontakty`
WHERE (`zakaznici_kontakty`.`zakaznici_id` IN (83))
Ale zobrazi data jenom z tabulky zakaznici_kontakty