Zmatek s použitím \Nette\Database\Table\Selection

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
theo
Člen | 57
+
0
-

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
+
0
-

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
+
0
-

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í.