ActiveRow, relace many-to-many – vypsání propojeného názvu bez iterací nad výsledky
- Milan Obrtlík
- Člen | 50
Dobrý den, mám tři DB tabulky (tři tečky znamenají, že tam jsou
ještě nějaké snad nepodstatné sloupce):
groups: group_id, name, ...
users: user_id, active_group_id, ...
users_groups: group_id, user_id
Zjednodušeně: uživatelé jsou rozděleni do skupin (many to many), active_group indikuje právě zvolenou skupinu.
Když chci vypsat všechny skupiny pro daného uživatele, vyberu je z databáze tímto dotazem:
$this->database->table('users_groups')->where('user_id', $user_id)->fetchAll();
a v Latte to vykreslím takto
<li n:foreach="$users_groups as $user_group">{$user_group->group->name}</li>
Nette si s tím poradí naprosto fenomenálně přesně jak je psáno v dokumentaci.
A teď věc, se kterou potřebuji poradit – jde vypsat právě zvolená skupina mimo foreach?
Přišel jsem jenom na toto
<span>{$users_groups[$user->selected_group_id]->group->name}</span>
Ale to vyžaduje mít nastavený primární klíč na tabulce
users_groups.group_id
a pak už nebude možné mít více
uživatelů ve skupině.
- Mysteria
- Člen | 797
Zkusil bych něco jako:
$user = $this->database->table('users')->wherePrimary(1);
echo $user->ref('groups', 'active_group_id')->name; // Aktivní skupina, možná půjde zkrátit na $user->active_group->name
foreach ($user->related('users_groups', 'user_id') as $userGroup) {
echo $userGroup->group->name; // Všechny skupiny
}
- Milan Obrtlík
- Člen | 50
Pánové, moc se omlouvám, zadal jsem to nepřesně. $user
je
objekt třídy Nette\Security\User
a ve skutečnosti id zvolené
skupiny beru pomocí $user->getIdentity()->selected_group_id
.
Není tedy možné využít vychytávek Nette\Database
.
I kdyby $user
byl objekt třídy Nette\Database
,
tak by to stejně prásklo další dva dotazy na DB, sice jsou to rychlé dotazy
a prakticky ničemu nevadí – ale když si to člověk řekne několikrát
než dosáhne funkčnosti daného bloku a celá aplikace se skládá
z několika takových bloků, hned máme nezanedbatelnou hromadu úplně
zbytečných dotazů.