Nette Database – relace 1:1 obráceně (bez column_id)
- semtex.989
- Člen | 75
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
@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
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
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
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.