Vyhledání výsledku podle parametrů z jiné tabulky
- quiced
- Člen | 85
Zdravím, už asi druhý den si lámu hlavu s jednou věcí. Chtěl bych si nechat zobrazit záznamy z jedné tabulky podle parametru z druhé. Pokud jsem hledat správně tak se tomuto říká spojování tabulek. Našel jsem několik témat zde na fóru, ale bohužel se mi to nepodařilo zprovoznit.
Vytvořil jsem si tento kód:
$products_id = $this->orderRepository->getProduct()->where('order_id', $id);
foreach($products_id as $product_id){
$products[] = $this->orderRepository->getProduct_table()->where('id', $product_id->product_id);
$this->template->product = $products;
};
$products_id mi vybere id produktu z jedné tabulky a ještě pouze záznamy, které odpovídají danému $id. Dejme tomu, že v $products_id mám načteny 2 id produktů, které pomocí toho foreache chci zobrazit. Toto řešení bohužel nefunguje protože mi to zobrazuje chybu s tím, že nemůže nalézt jednotlivé sloupce, které volám v šabloně.
Díky za pomoc :D
- Eda
- Backer | 220
Nevím, jestli chápu tvé databázové schéma správně, ale v Nette\Database by to mělo být nějak takto:
$this->template->products = $this->db->table('products')->where('order_id', $orderId);
(Samozřejmě je nanejvýše vhodné tento kód zabalit do nějaké funkce
v repository.)
…a pak v šabloně jen:
{foreach $products as $product}
<div>{$product->title}</div>
...
{/foreach}
Editoval Eda (8. 5. 2013 11:35)
- quiced
- Člen | 85
Pochopil jsi mě trochu špatně, ono se to i špatně vysvětluje.
Touto částí kódu:
$products_id = $this->orderRepository->getProduct()->where('order_id', $id);
si vyberu id produktů z jedné tabulky, ale těch ID je několik např. 1,2.
Potom potřebuju z druhé tabulky vybrat příslušné produkty a poslat je do šablony. Myslel jsem, že by to mohlo jít takto:
foreach($products_id as $product_id){
$products[] = $this->orderRepository->getProduct_table()->where('id', $product_id->product_id);
$this->template->product = $products;
};
ale jak už jsem psal v prvním příspěvku háže mi to chybu o neexistujícím sloupci v databázi i přesto, že tam ten sloupec je.
- quiced
- Člen | 85
Určitě tady je: http://i44.tinypic.com/1nzfvc.png
V tabulce order_product ve sloupci product_id jsou id produktů podle kterých se vybírají produkty v tabulce products.
- David Matějka
- Moderator | 6445
koukam, ze tam nemas nadefinovane cizi klice. kdyz si je nadefinujes, bude ti stacit zhruba takovyhle dotaz:
$this->orderRepository->getProduct_table()->where('order_product:order_id', $orderId);
//ve vyvojove verzi nette pak takhle
$this->orderRepository->getProduct_table()->where(':order_product.order_id', $orderId);
(pripadne pokud mas nejaky duvod nepouzivat klice nebo pouzivat myisam, tak prejmenuj tabulku products na product a pouzi conventional reflection misto discovered a melo by to fungovat snad taky)
nebo to muzes provest pomoci dvou dotazu:
$products_id = $this->orderRepository->getProduct()->where('order_id', $id)->select('product_id');
$this->orderRepository->getProduct_table()->where('id', $products_id);
do where muzes jako parametr totiz dat i Nette\Database\Table\Selection,
potom se provede ten dotaz odpovidajici selection a vezmou se hodnoty toho
sloupecku product_id (je definovan v ->select(), pokud by nebyl, bral by se
PK) a tyto hodnoty se daji do noveho dotazu do id IN(1,2,3..)
- Eda
- Backer | 220
- tabulky převeď na uložiště InnoDB, pokud už takové nejsou
- proč je jedna tabulka v množném čísle a jedna v jednotném? Doporučuju sjednotit
- nadefinuj si správně cizí klíče mezi tabulkami (to zajistí, že Nette\Database bude vědět, jak tabulky přijoinovat = pak se už o to nemusíš starat)
- pak použij tento kód:
$this->template->products = $this->db->table('products')
->where(':order_product.order_id', $orderId); // ve verzi 2.0.x pak 'order_product:order_id'
V šabloně pak již budeš mít k dispozici proměnnou
$products
s produkty požadované objednávky.
Tak Matěj byl rychlejší :-)
Editoval Eda (8. 5. 2013 13:28)
- Eda
- Backer | 220
V takové situaci bys měl mít cizí klíč ze sloupce
product_id
v tabulce order_products
ukazující na
sloupec id
v tabulce products
. Vůbec nevadí, že
id
má autoincrement.
Koukám, že používáš Adminer. Tam se dá přidat cizí klíč jednoduše pomocí odkazu v přehledu sloupců tabulky „přidat cizí klíč“…
- quiced
- Člen | 85
Jak přidat cizí klíč na to jsem přišel a obráceně to funguje, ale není potom problém v tom kódu
$this->template->products = $this->db->table('products')
->where(':order_product.order_id', $orderId);
když je tam tabulka products a ten cizí klíč bude u order_products?
a ještě jedna věc, nette database si podle toho cizího klíče sama propojí id produktu s product_id ?
aktuálně mi to píše chybu „No reference found for $products->order_products“
Ještě jednou díky za pomoc