Zmatek s použitím \Nette\Database\Table\Selection
- theo
- Člen | 57
Upřímně řečeno nestačím zírat. Práce s databází vypadá podle dokumentace jako procházka rajskou zahradou, nicméně buďto jsem natvrdlý, nebo je to zdokumentované ještě mizerněji než zbytek Nette (zatím to tak vypadá). Mohl by mi někdo vysvětlit jak se ta zatracená věc používá? Základ vypadá velmi jednoduše (mám takhle – https://doc.nette.org/cs/quickstart – vytvořené modely) a je i vcelku logický (a funkční :), moje databáze vypadá takto:
CREATE TABLE `roles` (
`id` varchar(20) NOT NULL,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci;
CREATE TABLE `users` (
`id` integer(11) NOT NULL AUTO_INCREMENT,
`username` varchar(20) NOT NULL,
...
PRIMARY KEY (`id`),
UNIQUE KEY (`username`),
CONSTRAINT FOREIGN KEY (`serial_id`) REFERENCES `serials`(`id`) ON UPDATE CASCADE ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci;
REATE TABLE `users_has_roles` (
`role_id` varchar(20) NOT NULL,
`user_id` integer(11) NOT NULL,
CONSTRAINT FOREIGN KEY (`role_id`) REFERENCES `roles`(`id`) ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE CASCADE ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci;
V třídě Authenticator
(která je v podstatě nachlup
stejná jako ta v dokumentaci (https://doc.nette.org/…thentication#…)
chci udělat toto:
<?php
...
$user = $this->users->where('username', $username)->fetch();
...
foreach ($user->related('users_has_roles') as $usersRole) {
$roles[] = $usersRole->role_id;
}
...
return new NS\Identity($user->id, $roles, $user->toArray());
?>
Problém je ovšem v tom, že ačkoliv mám v tabulce
users_has_roles
tři role pro jednoho uživatele, tak v
$roles
je vždy role pouze jedna (v debug panelu se píše, že
SQL dotaz, který tohle má vytáhnout má vracet tři řádky, když udělám
$user->related('users_has_roles')->count()
tak mi tvrdí, že
je tam řádek jen jeden). Naprosto netuším v čem by měl být problém.
Dokumentace k metodě related()
prakticky neexistuje a to co
jsem našel je formulováno tak, že to účel spíš zastírá (BTW:
v dokumentaci – https://doc.nette.org/cs/database –
se píše o variantě s ->through()
, která ale vyhazuje
výjimku, že je to deprecated – vtipné :).
Dále mi nefunguje nic z té slávy se spojováním tabulek. Tím mám na
mysli, že při pokusu o volání $usersRole->roles->name
se
dozvím pouze že „No reference found for $users_has_roles->roles.“.
Tuším, že to má co do činění s jakousi databázovou reflexí, ale
NIKDE jsem nenašel žádný ucelený příklad jak takovou
věc nastavit (kromě nic neříkající zmínky v config.neon, což je
upřímně řečeno to poslední místo kde bych něco takového hledal).
Z dokumentace naprosto nejasná je i situace kolem escapování řetězců,
které posílám do dotazů. Podle toho co jsem se díval do kódu se žádné
escapování nedělá, podle dokumentace k PDO lze escapovat celý dotaz
najednou pomocí PDO::prepare()
, což je mi ale ve fluent rozhraní
k ničemu a jinou metodu, která by tuto problematiku řešila, jsem nenašel
(kromě obligátní mysql_escape_string()).
Doufám, že mi (a nejen mě) tohle bude schopen někdo rozumně vysvětlit, protože z tohoto prvního pokusu o použití Nette 2.0 jsem těžce rozčarovaný (0.9ku jsem použil na několik aplikací vcelku bez problémů). Možná, že je to vymyšleno geniálně, ale bez odpovídající a aktuální dokumentace je to k ničemu.
Editoval theo (15. 3. 2012 0:17)
- theo
- Člen | 57
Nu dobrá tak problém s jedním řádkem jsem vyřešil s pomocí tohoto příspěvku (a po vymazání cache :) (https://forum.nette.org/…es-vazbu-m-n#…), nicméně jak si vyrobit a nastavit vlastní DatabaseReflection, to jsem prostě nenašel.
Jinak podle toho co jsem si zde přečetl by mělo prý stačit zapnout
DiscoveredReflection
což se prý provede v config.neon s pomocí
reflection: discovered
v části database
, nicméně
u mě to teda žádný efekt nemělo (podotýkám, že na použití cizích
klíčů jsem dost vysazený, takže databáze je zcela jistě obsahuje].
- Caine
- Člen | 216
Jooo, jestli chceš používat nette v tomhle stavu, budeš muset procházet zdrojáky nette (sem tam příklady a občas i ty videa na youtube), abys pochopil, jak to funguje, protože v dokumentaci, kterou píšou lidi, co to maj podkuží a vynecháváj takový malý, důležitý detaily, to nenajdeš. Naprosto chápu tvoji frustraci s dokumentací, v prvních pár tejdnech jsem měl každou chvíli chuť se na to v****t, protože je to skutečnej porod, ale když to překonáš, nakonec se to vyplatí.