Řetězení where in na jeden sloupec
- regy42
- Člen | 8
Ahoj,
potřeboval bych zřetězit where na jeden sloupec asi takto:
$this->context->database->table("products")->where("id",array(1,2,3))->where("id",array(2,3,4))
ale nette druhé where ignoruje, protože podmínka míří na stejný
sloupec (nevím proč, protože databáze normálně dotaz
SELECT * FROM products WHERE id IN (1,2,3) and id IN (2,3,4)
přijme).
Když by ve druhém where bylo třeba id2, tak už se to provede. Nevíte proč a jak to obejít? (jinak, než spojit nejdřív všechna pole a pak je dát do jednoho where, to se mi zdá neefektivní, nebo to tak může klidně být?)
Předem díky :-)
- regy42
- Člen | 8
Když takhle mi ta konstrukce moc nevyhovuje, protože to mám tak, že první podmínka je v dotazu vždy a druhá (a další) se pak přidávají ve foreach:
<?php
$products = $this->context->database->table("products")->where("id",array(1,2,3))
foreach($filters as $name => $values) {
$products = $products->where("id",$values)
}
?>
Přes ten context jsem to měl, protože jsem začal v nette před dvěma týdny a jediný způsob, jak jsem byl schopen se propojit s databází, byla, že jsem si udělal service database :-) (protože to je dobré popsáno v tutoriálech :)). Teď už jsem to pochopil, jak to udělat bez toho, je tedy lepší si to nadefinovat v base presenteru
<?php
public function __construct(Nette\Database\Connection $db)
{
$this->database = $db;
}
?>
než to tahat přes ten context? Zase tam bych si mohl přidat nějaké speciální věci, ale to vlastně kdybych potřeboval, tak pak stačí v construct zapsat $this->database = $this->context->…, nojo já to časem poberu :-).
Jinak, než jsi napsal to tedy nejde? Tak si hold nejdřív načtu pole a pak teprve udělám ten dotaz. Jinak potřebuju tedy and, ale to je úplně jedno.
Díky!
- JHadamcik
- Člen | 47
regy42 napsal(a):
Když takhle mi ta konstrukce moc nevyhovuje, protože to mám tak, že první podmínka je v dotazu vždy a druhá (a další) se pak přidávají ve foreach:
<?php $products = $this->context->database->table("products")->where("id",array(1,2,3)) foreach($filters as $name => $values) { $products = $products->where("id",$values) } ?>
Přes ten context jsem to měl, protože jsem začal v nette před dvěma týdny a jediný způsob, jak jsem byl schopen se propojit s databází, byla, že jsem si udělal service database :-) (protože to je dobré popsáno v tutoriálech :)). Teď už jsem to pochopil, jak to udělat bez toho, je tedy lepší si to nadefinovat v base presenteru
<?php public function __construct(Nette\Database\Connection $db) { $this->database = $db; } ?>
než to tahat přes ten context? Zase tam bych si mohl přidat nějaké speciální věci, ale to vlastně kdybych potřeboval, tak pak stačí v construct zapsat $this->database = $this->context->…, nojo já to časem poberu :-).
Jinak, než jsi napsal to tedy nejde? Tak si hold nejdřív načtu pole a pak teprve udělám ten dotaz. Jinak potřebuju tedy and, ale to je úplně jedno.
Díky!
Do BasePresenteru to nedávej. Presenter má presentovat a model má pracovat s databází. Řekněme, že si v modelu vytvoříš třídu Products(.php) a tam si předáš to $this->database. Celá práce s databází má být oddělena do modelu. Čili kupříkladu v presenteru nějakém se zeptáš
$products = $this->products->getBlaBlaBla($params);
V Products.php budeš mít metodu getBlaBlaBla a tam zpracuješ jak má fungovat.
$this->context se dá používat, ale odstřelíš tím kompletní DI a to mi nepřijde rozumné. DI ti dává čistotu v kódu, při psaní testů vidíš co všechno si musíš namockovat apod.
Pozn: $this->products v tom presenteru si injectneš.
Ten foreach co sis napsal by měl fungovat a asi jsem nepochopil hned napopré jak to myslíš.
Editoval JHadamcik (16. 7. 2013 13:29)
- Michal Vyšinský
- Člen | 608
A proč potřebuješ dvakrát „where“? Nestačilo by toto?
$ids = array(1,2,3);
foreach($filters as $name => $values) {
$ids = array_merge($ids, $values);
}
$products = $this->context->database->table("products")->where("id", $ids);
- JHadamcik
- Člen | 47
CherryBoss napsal(a):
A proč potřebuješ dvakrát „where“? Nestačilo by toto?
$ids = array(1,2,3); foreach($filters as $name => $values) { $ids = array_merge($ids, $values); } $products = $this->context->database->table("products")->where("id", $ids);
Psal
regy42 napsal(a):
Nevíte proč a jak to obejít? (jinak, než spojit nejdřív všechna pole a pak je dát do
jednoho where, to se mi zdá neefektivní, nebo to tak může klidně být?)
- Michal Vyšinský
- Člen | 608
Aha, omlouvám se, to jsem nějak přehlédl. Jinak si myslím, že to nebude o nic méně efektivní než řetězit where.
- regy42
- Člen | 8
Jo, už vím, proč potřebuju řetězit where, chci průnik id (aby to odpovídalo všem filtrům), musel bych tedy v php ještě udělat ten průnik, proto jsem zvolil řetězení where, jen už jsem ten důvod zapomněl :-). Dělám nějaký katalog, není tam žádný presenter, kde by se netahalo z databáze.
Já vím, že bych na to měl používat modely, jen jsem php vždy jel bez frameworku, tak mi ten kód už teď přijde tak zjednodušený, že další zjednodušení presenteru využitím modelu mi přišlo zbytečné, ale asi to aspoň utěch produktů udělám, protože tam právě už začínají být více, než jednořádkové primitivní selecty.
Mám si tedy napsat něco takového:
<?php
class Products extends Nette\Object
{
protected $database;
public function __construct(Nette\Database\Connection $db)
{
$this->database= $db;
}
public function getProducts($category)
{
//diskutovaný dotaz
return $products;
}
}
?>
to uložím do models a pak to musím dávat do config.neon nebo jak to nejlépe injectnu do presenteru Products, když nemám používat to context? A mohli byste prosím ještě trošku popsat, proč to nemám používat nebo jak to je? A ještě jeden doraz, kdybych měl třeba ten model Products a pak chtěl udělat nějakou nádstavbu zvlᚍ, tak lze místo ‚class Name extends Nette\Object‘ napsat ‚class Name extends Product‘, aby to umělo i to co products nebo je to nesmysl?
Co mi přijde na těch modelech trochu nesmyslné, je množství toho kódy, když chci třeba jen obyčejně selectnout jednu tabulku, musím přece pokaždé udělat nový soubor s novou třídu, tam udělat stejný construct a pak tam udělat stejnou funkci třeba getTable. Nebo se to praktikuje jinak právě třeba tím že se extenduje nějaká základní?
Děkuji mohokrát za ochotu a za vaší rychlost.
- JHadamcik
- Člen | 47
Bohužel ti neodpovím na všechny tvé dotazy (nejsem ani zdaleka nette guru), ale:
- Jak si modely navrhneš tak modely máš. Nejsem si jistý jestli existuje pravidlo „jedna tabulka jeden soubor v modelu“.
- Products si zaregistruješ v config.neon jako službu (products: Products) – db se předá samo
- Ano pak si přes inject natáhneš do Presenteru Products model.
Modely složité nejsou a používají se kupříkladu kvůli tomu, že teď máš db nad mysql, notorm a zítra ti může běžet na postgres, orm a měníš pouze model.
//Edit: alespoň tak to zatím chápu já. Navíc MVP je MVP a podle toho jedeme :D
Editoval JHadamcik (16. 7. 2013 14:34)
- regy42
- Člen | 8
JHadamcik napsal(a):
Modely složité nejsou a používají se kupříkladu kvůli tomu, že teď máš db nad mysql, notorm a zítra ti může běžet na postgres, orm a měníš pouze model.//Edit: alespoň tak to zatím chápu já. Navíc MVP je MVP a podle toho jedeme :D
To je pravda, ikdyž momentálně jde spíš o rychlokvašku, ale aspoň se to naučím :).
Jenom mi není jasné, proč mám zapomenout na ten context …
- JHadamcik
- Člen | 47
regy42 napsal(a):
JHadamcik napsal(a):
Modely složité nejsou a používají se kupříkladu kvůli tomu, že teď máš db nad mysql, notorm a zítra ti může běžet na postgres, orm a měníš pouze model.//Edit: alespoň tak to zatím chápu já. Navíc MVP je MVP a podle toho jedeme :D
To je pravda, ikdyž momentálně jde spíš o rychlokvašku, ale aspoň se to naučím :).
Jenom mi není jasné, proč mám zapomenout na ten context …
Jak už jsem psal. context zabíjí DI. Pokud chceš mít (alespoň já to tak mám) aplikaci hezkou tak používej DI. DI je založeno na tom, že nic si nic nezískává a vše je tomu dodáno.
context jde proti tomu.
- Příklad
- DI:
Model dostane připojení k databázi v constuructu
- context
Sr*t na předávání připojení k DB, vezmeme si to násilím
Taky mi dlouho trvalo než mi někdo dokázal vysvětlit proč sakra nemůžu používat context. Na argument toho člověka už jsem zapomněl jinak bych ti ho řekl, ale od té doby jej prostě nepoužívám. Vždy když chceš napsat context si uvědom, že to co potřebuješ jde injectnout.