Vlozenie zaznamu a jeho vlastnosti
- cujan
- Člen | 410
Caute potrebujem vlozit do DB zaznam volajme ho ze „Mineral“ ten ma
nejake vlastnosti napr. farba. Problem je v tom ze tych farieb moze byt ku
jednemu mineralu viacero. Ako to poriesit? Vytvorit pomocnu tabulku MinerelFarba
a takto ukaldat zaznamy o farbe? A ako riesi samotne ukladanie, ked napr.
nepoznam id vkladaneho zaznamu?
A ak takto tak v sablone by ste to ako funkcne riesili, ide mi o to aby to
mal uzivatel co najjednoduchsie?
Vdaka
Vdaka
- frosty22
- Člen | 373
Tomuhle se říká První normálová forma, a je to správně přesně tak jak říkáš, tj. mít tabulku MineralFarba.
A k tomu ukládání ti dopomůže poslední vložené ID do databáze, což se v případě Nette/Database ukládá po vložení do databáze (v případě AUTOINCREMENTu) do dané property objektu, tj:
<?php
$conn = // Připojení: Connection
$mineral = $conn->table("Mineral")->insert(array("name" => "Diamant", "height" => 15, ...));
$colors = // Pole barev
foreach ($colors as $color) {
$conn->table("MineralFarba")->insert(array("mineral_id" => $mineral["id"],
"farba" => $color));
}
?>
Je to vystřihlé od oka, takže možná tam je překlep někde, ale podstatná je ten prvek $mineral[„id“], který pokud máš tedy onen inkrementovanej sloupec pojmenován id tak bude obsahovat ID vloženého záznamu.
- frosty22
- Člen | 373
Jinak ještě bys měl mít tabulku „Farba“, kde bude seznam oněch barev a ta MineralFarba je tedy propojovací mezi nimi idelně.
Jo ještě dodatek, pokud s návrhy tabulek nemáš zkušenosti, tak se na to jistě podívej, jelikož je ještě potřeba mít tabulky v enginu INNODB, a potom nastavit tzv. cizí klíče, abys měl správnou integritu dat.
Konkrétně v tomto případě:
- INDEX na sloupec mineral_id tabulky MineralFarba
- Cizí klíč tohoto sloupce na sloupec id tabulky Mineral (čili na primární klíč), a v tomto případě s nastavením CASCADE
- INDEX na sloupec farba_id tabulky MineralFarba
- Cizí klíč na primární klíč tabulky Farba (tyto kroky 3 a 4 jsou stejné jako 1 a 2 jen pro tabulku Farba)
- Nastavit přes oba sloupce mineral_id a farba_id unikátní index v tabulce tedy MineralFarba
Těmiti kroky zaručíš integritu dat, takže nepůjde přidat minerálu barva, která neexistuje (zaručí krok 4). Zároveň nepůjde jednomu a tomu samému přidat dvakrát stejnou barvu (zaručí krok 5). Též nepůjde vložit do propojovací tabulky například neexistující ID minerálu (zaručí krok 2).
A ona vlastnost CASCADE znamená, že pokud odstraníš minerál, tak se automaticky odstraní i prvky odpovídající tomuto cizímu klíči, tj. všechny řádky v tabulce MineralFarba, které mají ID odstraňovaného minerálu.
U barvy bych ale namísto CASCADE vybral RESTRICT, čili pokud budeš chtít odstranit barvu, kterou mají přiřazené některé minerály, tak odstranit nepůjde (pokud bys i tady dal CASCADE tak ti to samozřejmě při odstranění barvy odstraní všechny propojení mezi minerálem a tou barvou, což zde není logické).
Díky integritě dat pak nemusíš (a neměl bys) odstraňovat ony data mezi propojovacími tabulkami, stačí mít pouze dobře nastavené klíče a vše se řeší kaskádově samo.
- Vojtěch Dobeš
- Gold Partner | 1316
Doufám, že to není mimo, ale pro výběr barvy lze použít
type="color"
. V Nette to znamená:
$form->addText('farba', 'Farba');
->setType('color');
A (bohužel) pro většinu prohlížečů bude třeba doplnit nějaké javascriptové udělátko, které doplní podporu tam, kde nativní chybí.
- frosty22
- Člen | 373
Tak na tohle se hodí checkboxy, když onen minerál může mít více barev, pokud by mohl jednu tak select, ale takto checkboxy.
Musíš na to však vytvořit kontajner, abys mohl ukládat ony barvy jako prvky s jejich číslenými indexy.
<?php
$colorContainer = $form->addContainer("colors");
$colors = $this->db->table("Farba");
foreach ($colors as $color)
$colorContainer->addCheckbox($color["id"], $color["name"]);
?>
Edit:
Alternativně je možné použít doplněk Checkboxlist,
který toto udělá za sebe a pouze dáš:
<?php
$form->addCheckboxList("color", "Farba", $this->db->table("farba")->fetchPairs("id", "name"));
?>
Editoval frosty22 (20. 10. 2012 10:41)
- frosty22
- Člen | 373
Jak tam máš onen link na doplněk, tak doplněk = addon = plugin = něco co je potřeba doinstalovat :)
Máš tam ten odkaz, na kterém je to ke stažení a i návod jak na to, a co se týče „instalace“ tak to v podstatě stačí jen zkopírovat do libs a je to ihned součást distribuce, a potom tedy zaregistrovat, což lze jednoduše zavoláním:
<?php
Nette\Forms\Controls\CheckboxList::register();
?>
a toto stačí uvést někde před jeho použitím, tj. třeba buď v metodě startup presenteru ve kterém to budeš používat, či pokud to bude používat na více místech tak v metodě startup tvého BasePresenteru