Vlozenie zaznamu a jeho vlastnosti

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
cujan
Člen | 410
+
0
-

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
+
0
-

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
+
0
-

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ě:

  1. INDEX na sloupec mineral_id tabulky MineralFarba
  2. Cizí klíč tohoto sloupce na sloupec id tabulky Mineral (čili na primární klíč), a v tomto případě s nastavením CASCADE
  3. INDEX na sloupec farba_id tabulky MineralFarba
  4. Cizí klíč na primární klíč tabulky Farba (tyto kroky 3 a 4 jsou stejné jako 1 a 2 jen pro tabulku Farba)
  5. 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.

cujan
Člen | 410
+
0
-

Vdaka za fantasticky komentar…fakt klobuk dole, ma to hlavu aj patu…este raz vdaka…

frosty22
Člen | 373
+
0
-

Rád jsem pomohl a budu ještě radši když to pomůže a zkusíš cizí klíče :)

cujan
Člen | 410
+
0
-

uz som si cela o tom nastudoval, a aj vela som pochopil a jedno je jasne, oplati sa venovat na zaciatku viac casu integritnym obmedzeniam DB, o to menej clovek potom musi odchytavat problemov kodom, lebo DB si to strazi sama…a tam je ta sila :-)

cujan
Člen | 410
+
0
-

Cau este jedna vec, co sa tyka sablony, aky prvok by sa dal podla teba pouzit na vyberanie tej farby pre ten mineral? Nejaky textfield alebo take nieco?

vdaka

Vojtěch Dobeš
Gold Partner | 1316
+
0
-

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í.

cujan
Člen | 410
+
0
-

Ano kus mimo, ja ma farby v DB a taham ich z ciselnika, a potrebujem ku jednemu prvku co vkladam do db priradit viac farieb, databazovo to uz mam poriesene len to este riesim ako najvhodnejsie to poriesit z pohladu uzivatela…

cujan
Člen | 410
+
0
-

ale aj tak vdaka za reakciu :-)))

frosty22
Člen | 373
+
0
-

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)

cujan
Člen | 410
+
0
-

super, ten chceckBoxList vyzera super, len je sucastou distribucie alebo ho treba doinstalovat?

frosty22
Člen | 373
+
0
-

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

cujan
Člen | 410
+
0
-

Ja viem tupe otazky, ale povacsine az ked sa clovek dozvie odpoved,tak si uvedomi aka hlupa bola otazka :-))

vdaka

cujan
Člen | 410
+
0
-

Cau
cize nahla som to do libs/nette/forms/controls

do base presentera som vlozil do startup

<?php
Nette\Forms\Controls\CheckboxList::register();
?>

a hodilo mi hlasku

Call to undefined static method Nette\Forms\Controls\CheckboxList::register()

a som skoncil :-)

vdaka

cujan
Člen | 410
+
0
-

Vyriesene problem bol v bootstrap.php neskoro som registroval komponentu…stacilo registraciu posunut par riadkov vyzsie…

cujan
Člen | 410
+
0
-

Caves

vkladanie udajov ma poriesene, len kus tak hutam ako ich teraz nacitat naspat do sablony? Teda samostatne udaje o mineraly a samostatne udaje o mineralFarba nie je problem ale ako ich nacitat spolu? teda poparovat?