Nette Database – relace 1:1 obráceně (bez column_id)

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

Narazil jsem na problém Nette\Database (asi to bude stejné i v NotORM), kde spojuji tabulku product s tabulkou product_description.
V tabulce products nemám sloupec description_id, ale naopak tabulka product_description má slouec product_id.

Ukážu část databáze:

tabulka product

id int(22) Auto Increment

referenced_id int(11) NULL

external_id int(11) NULL

code varchar(64) NULL

tabulka product_description

product_id int(11)

language_id int(11)

name varchar(255)

description blob

Samozřejmě mám nadefinované cizí klíče a UNIQUE nad kombinací product_id – language_id

pokud zavolám např. toto tak to skončí chybou úrovně E_WARNING:

<?php
foreach($connection->table("products") as $product)
	echo $product->product_description['name'];
	echo $product->related("product_description")->fetch()->name; // tohle by asi chodilo, ale syntaxe není úplně přívětivá
?>

Bohužel mi nepomohla ani žádná příručka jako http://sql-cross-queries.freexit.eu/

petr.pavel
Člen | 535
+
0
-

@JuniorJR: On říkal „nad kombinací“, ne jednotlivě. Takhle je to ok.

@semtex.989:
Ten první případ ($product->product_description[‚name‘]) by se odkazoval do tabulky rodiče, což není tvůj případ. Byl by, kdybys třeba z tabulky language chtěl zjistit název jazyka.

Druhý případ je správně, protože ty se chceš dotázat tabulky dětí. Zkrátit nejde – z návrhu databáze je patrné, že dotaz může vrátit víc řádků, proto musíš volat jeden fetch(), abys z nich vzal první záznam. Ještě taky bys měl testovat, jestli dotaz vůbec něco vrátil – třeba pomocí count(), myslím, že by šel i empty().

semtex.989
Člen | 75
+
0
-

No celkově ta syntaxe s fetch je docela odpudivá…
Nakec jsem to vyřešil tak, že jsem do tabulky products dal sloupec description_id s cizím klíčem a tabulce description jsem přidal sloupec ID s auto incrementem.

Takto to otočit sice ve mně zanechávává dojem špatně navržené databáze, ale hezčí a kratší kód vítězí…

petr.pavel
Člen | 535
+
0
-

Ale vždyť tvůj product má víc description a z nich volíš to jedno správné podle aktuálního jazyka. Nebo se pletu? Proč jinak bys měl v product_description atribut language_id?

Takže naopak, měl bys použít to svoje druhé řešení a doplnit where() (tohle píšu z hlavy):

$product->related("product_description")->where('language_id', $user->getIdentity()->language_id)->fetch()->name

„Řešení“ s description_id by fungovalo jen pro jeden jazyk. To už můžeš rovnou ty tabulky sloučit.

Moc nerozumím tomu, co ti vadí na tom dlouhém zápisu. Přesně odráží logiku db modelu, což je podle mě výtečné.

Ale jak je libo :-)

semtex.989
Člen | 75
+
0
-

No ne tabulka products_description bude mít sloupec entry_id (auto increment) a sloupec id tedy nebude auto increment. Potom může mít jedno id třeba tři jazyky. Každopádně je i to ale blbě.. to už jsem pocítil.

Chtěl jsem si nad tím samozřejmě napsat obálky pro jednotlivé modely, aby se dala psát např. syntax

$product->description

za předpokladu, že už vyšší vrstva modelu zapodmínkovala jazyk, produkty které nejsou disabled, apod.
Celkově se mi vůbec NotORM pro tento úkol nezdá vhodné (proto se taky jmenuje NotORM).

Asi zkusím Doctrine 2, jak propagoval tuším HosipLan.