Nette database explorer vazba M:N
- Dapler
- Člen | 2
Ahoj,
píši aplikaci, kde mám určité výzvy (db tabulka challenges) a uživatele
(db tabulka users) vzhledem k tomu, že mezi těmito tabulkami je vazba M:N
mám zde ještě tabulku challengeUser, kde mám dva sekundární klíče a to
users_id a challenges_id, tyto jsou napojeny na primární klíče tabulek
challenges a users. V tabulce challengesUsers mám progres uživatele
v určité výzvě, do této tabulky by se v ideálním případě záznam
zapsal až ve chvíli, kdy by jí začal plnit. Potřebuji uživateli vypsat
všechny výzvy, které ještě nemá úplně splněné, vzhledem k tomu, že
už tady jsem se zarazil, protože jsem měl problém k tomu vymyslet vůbec
dotaz v SQL, natož v nette database exploreru, který se aktuálně učím
stejně jako celé nette, proto jsem se tedy rozhodl, že v challengeUser bude
mít prostě vždy každý uživatel záznam s každou výzvou (toto není
předmětem dotazu, nicméně pokud by někoho napadlo, jak toto vyřešit tak,
aby záznam v challengeUser byl až ve chvíli, kdy začne uživatel plnit, byl
bych rád).
Teď k dotazu, potřebuji vypsat uživateli všechny jeho výzvy, kde progres < 10000, jenže narážím už při tvorbě dotazu.
$responseChallanges = $this->database->table('challengeUser');
$challanges = array();
foreach($responseChallanges as $key => $response)
{
dump($responseChallanges->users->username);
}
protože mi to vždy vracelo chybu, přesel jsem k dump pro testování, nicméně jak jsem popisoval strukturu databáze výše, uživatel má aktivní výzvu, proto získám data z challengesUsers, kde je cizí klíč users_id a challenges_id, chci z tabulky users dostat username uživatele s aktivní výzvou, to mi ale vrací chybu:
PHP Warning: Undefined property: Nette\Database\Table\Selection::$users
nenapadá někoho, prosím, v čem by mohla být chyba? Děkujo
- m.brecher
- Generous Backer | 863
@Dapler
PHP Warning: Undefined property: Nette\Database\Table\Selection::$users
Musíš si vyžádat sloupec na řádku, nikoliv na celé tabulce:
// tohle je špatně
foreach($responseChallanges as $key => $response)
{
dump($responseChallanges->users->username);
}
// toto by mělo být správně, $key bych vyřadil, tabulka nemá id jako primární klíč
foreach($responseChallanges as $response)
{
dump($response->users->username);
}
U spojovací tabulky je potřeba definovat primární klíč jako kombinaci obou cizích klíčů (sekundárních).
Z analytického pohledu je potřeba v databázi zaznamenat entitu ihned, jakmile se o ní v business procesu třeba jen uvažuje. Životní cyklus entity pak řídíš stavovými parametry. Jiný postup, kdy se o entitě již uvažuje, ale nezapíše se do databáze povede rychle k zesložitění kódu.
progres
Progres uživatele v nějaké výzvě je zřejmě klasický business proces, kdy uživatel prochází nějakými fázemi. V první fázi, kdy Ty nechceš záznam do tabulky challengeUser vůbec zapisovat bych tam záznam zapsal s nějakým stavovým polem activated = false. Po aktivaci nastavit activated = true.
Zdá se mi, že tabulka challengeUser není obyčejná spojovací tabulka, ale plnokrevná entita reprezentující nějaký business process. Takže by bylo lepší tam dát samostatný primární klíč id a potřebná data na řízení procesu – stavová pole a nějaké datumy apod…
Editoval m.brecher (6. 2. 1:18)