Filter udajov z databazy podla vlastnosti
- cujan
- Člen | 410
Caute
potreboval by som urobiť vlastný filter udajov z databazy:
proste mam mineral co ma vlastnosti: farba, lesk, tvrdost
a potrebujem aby ak napr. uzivatel za dal farba = zelena tak mu vypisalo
mineraly, ktore su zelenej farby..
resp. zeleny a leskly tak vypise tie…
ako by som mal podla vas postupovat?
Vdaka
- hAssassin
- Člen | 293
class Mineral extends Repository {
...
public function filterByProperty($property, $value) {
return $this->dbcomm->table('mineral')->where($property.'.name = ?', $value);
}
...
}
Psano z hlavy a mozna to sou bludy, uz je pozde a dlouho sem s NetteDB nedelal, ale principielne jde o dotaz zhruba takovyto:
SELECT * FROM mineral m JOIN color c ON m.id = c.material_id WHERE c.name = 'zelena'
A potom $property
je nazev tabulky ‚color‘ a
$value
je hodnota podle ktery chces filtrovat, cili ‚zelena‘.
Viz srovnani
- echo
- Člen | 134
hAssassin napsal(a):
Psano z hlavy a mozna to sou bludy, uz je pozde a dlouho sem s NetteDB nedelal, ale principielne jde o dotaz zhruba takovyto:SELECT * FROM mineral m JOIN color c ON m.id = c.material_id WHERE c.name = 'zelena'
Přesně tomuhle se snaží Nette Database vyhnout. Místo join položí 2 dotazy. Stačí to vyzkoušet a číst dokumentaci https://doc.nette.org/cs/database#….
- enumag
- Člen | 2118
NDB funguje tak že pokládá samostatný dotaz na každou tabulku ze
které potřebuješ číst data. Automatické joiny vytváří
pouze pokud je potřebuješ ve where podmínkách, ale takto
vytvořené joiny slouží jen k filtrování výsledku a
nikoli ke čtení dat (čtení můžeš vynutit klauzulí
->select('join_column.column')
, ale to nedoporučuji). Výjimku
z výše uvedeného tvoří agregace.
Takže ano, pro 3 tabulky položí 3 dotazy.
Editoval enumag (24. 1. 2013 10:45)
- enumag
- Člen | 2118
Teď když se dívám na ten tvůj dotaz tak problém bude možná jinde. Je
sloupec material_id
primárním klíčem tabulky
color
? Pokud ano tak máš imho chybný návrh databáze, FK by
vždy měl ukazovat na PK té cizí tabulky. Mám pocit, že NDB jiný způsob
ani nepodporuje (@hrach: můžeš potvrdit?).
- cujan
- Člen | 410
to bol len hypoteticky priklad, cize skutocna struktura mojich tabuliek
mineral(id(PK), nazov)
farba(id(PK), nazov)
mineralFarba(idMineral, idFarba) – ktoru farbu ma mineral, lebo jeden moze
obsahovat viacero farieb
a cudzie kluce su idMineral ma mineral.id a idFarba na farba.id
a ja potrebujem dostat mineraly, ktore maju pridelenu urcitu farbu…
dikes
- enumag
- Člen | 2118
Jedním z důvodů je, že ta dvojtečková notace se velmi pravděpodobně bude měnit. Na GitHubu už nějakou dobu visí hotový pull request, ale David se k tomu pokud vím ještě nevyjádřil…
Jinak místo dokumentace je k dispozici hrachova přednáška.
- enumag
- Člen | 2118
$connection->table('mineral')->where([
'mineralFarba:farba.nazov' => [ $barva1, $barva2 ],
'mineralLesk:lesk.nazov' => $lesk,
]);
Edit: Výše uvedený příklad je pro „nebo“, pro „a“ je to
složité. Dá se to pomocí SqlLiteral a
EXISTS ... AND EXISTS ...
.
Editoval enumag (24. 1. 2013 22:38)
- cujan
- Člen | 410
Cau filter mi uz funguje, len by som sa chcel spytat na zopa vylepseni?
ako docielim aby ak zo select boxu vyberiem farbu tak sa mi hned na stranke pregeneroval zozonam mineralov bez toho aby sa mi ten vzber v tom select boxe stratil … take daco ako vyber vysledkov niekde na pozadi (interaktivne – podobne ako ked napr. pisem v google nieco vo vyhladavaci a internaktivne sa mi zobrazuju vysledky)
dufam ze som to napisal aspon trocha zrozumitelne :-)
vdaka
- enumag
- Člen | 2118
Ne nic takového. V prohlížeči běží JavaScript, který na pozadí odesílá asynchronní požadavky na server (ajax). Server požadavek dostane úplně stejně jako každý jiný, jen s nějakou hlavičkou navíc která umožňuje Nette ajax detekovat a zachovat se podle toho.
EDIT: Budeš potřebovat doplněk pro zpracování odpovědí. V současnosti je asi nejlepší ten od @Vojty Dobeše.
Editoval enumag (25. 1. 2013 12:07)
- cujan
- Člen | 410
No tak som zacals ajaxom :)
so startovacieho prikladu som si skopiroval .js subor
<?php
jQuery.ajaxSetup({
cache: false,
dataType: 'json',
success: function (payload) {
if (payload.snippets) {
for (var i in payload.snippets) {
$('#' + i).html(payload.snippets[i]);
}
}
}
});
// odesílání odkazů
$('a.ajax').live('click', function (event) {
event.preventDefault();
$.get(this.href);
});
// odesílání formulářů
$('form.ajax').live('submit', function (event) {
event.preventDefault();
$.post(this.action, $(this).serialize());
});
?>
nasledne som ho nalinkoval v @layout.latte podla navodu
potom som potrebny formular pomocu ktoreho chcem filtrovat mineraly obalil do tagu {snippet}
<?php
{snippet}
{form filterForm}
<table>
<tr>
<th>{label vonkajsiVzhlad/}</th>
<td>{input vonkajsiVzhlad}</td>
</tr>
<tr>
<th>{label farba/}</th>
<td>{input farba}</td>
</tr>
<tr>
<th>{label tvrdostOd/}</th>
<td>{input tvrdostOd}</td>
</tr>
<tr>
<th>{label tvrdostDo/}</th>
<td>{input tvrdostDo}</td>
</tr>
<tr>
<th>{label vryp/}</th>
<td>{input vryp}</td>
</tr>
<tr>
<th>{label lesk/}</th>
<td>{input lesk}</td>
</tr>
<tr>
<th>{label priepustnostSvetla/}</th>
<td>{input priepustnostSvetla}</td>
</tr>
<tr>
<th>{label create/}</th>
<th>{input create}</th>
</tr>
</table>
{/form}
{/snippet}
?>
len tu som sa sekol, stratil a nechapem ako mam postupovat dalej, ak chcem aby ak zmenim hociktoru polozku vo forme nech sami pregeneruje vysledna tabulka s vyseldkami (tuto v popisoch neuvadzam)
vdaka