Spojení dvou tabulek vyhazuje neexistující referenci, i když existuje

ForestCZE
Člen | 209
+
0
-

Ahoj, je tu několik příspěvků o spojování tabulek, četl jsem i dokumentaci, ale stále se mi nedaří to rozchodit.

$test = $this->database->getChatRooms()->joinWhere('chat_permissions', 'id = chat_id')->fetchAll();
foreach($test as $t)
{
	bdump($t['name']);
}
CREATE TABLE `chat_rooms` (
  `id` int(11) NOT NULL,
  `name` longtext COLLATE utf8_czech_ci NOT NULL,
  `datetime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `author` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci;

CREATE TABLE `chat_permissions` (
  `id` int(11) NOT NULL,
  `chat_id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci;

ALTER TABLE `chat_rooms`
  ADD PRIMARY KEY (`id`);

ALTER TABLE `chat_permissions`
  ADD PRIMARY KEY (`id`),
  ADD KEY `chat_id` (`chat_id`);

ALTER TABLE `chat_rooms`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3;

ALTER TABLE `chat_permissions`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=5;
ALTER TABLE `chat_permissions`
  ADD CONSTRAINT `chat_permissions_ibfk_1` FOREIGN KEY (`chat_id`) REFERENCES `chat_rooms` (`id`);

Error: No reference found for $chat_rooms->chat_permissions.

Co je špatně? Děkuji.

David Matějka
Moderator | 6445
+
0
-

jedná se o „has many“ referenci, takže tam musí být dvojtečka. nějak takhle

->joinWhere(':chat_permissions', 'id = :chat_permissions.chat_id')
ForestCZE
Člen | 209
+
0
-

David Matějka napsal(a):

jedná se o „has many“ referenci, takže tam musí být dvojtečka. nějak takhle

->joinWhere(':chat_permissions', 'id = :chat_permissions.chat_id')

Hlásí mi to, že v obou tabulkách je sloupec id, takže to neví, který je který. V Tracy mi vylezlo:

LEFT JOIN `chat_permissions` ON `chat_rooms`.`id` = `chat_permissions`.`chat_id` AND (`id` =
`chat_permissions`.`chat_id`)

A já bych to potřeboval jenom takto:

LEFT JOIN `chat_permissions` ON `chat_rooms`.`id` = `chat_permissions`.`chat_id`
David Matějka
Moderator | 6445
+
0
-

a potrebujes vubec joinWhere? ten se vlastne pouziva, kdyz chces neco joinovat s nejakou dalsi podminkou. ceho chces dosahnout?

ForestCZE
Člen | 209
+
0
-

David Matějka napsal(a):

a potrebujes vubec joinWhere? ten se vlastne pouziva, kdyz chces neco joinovat s nejakou dalsi podminkou. ceho chces dosahnout?

V Database Core to vypadá takto:

public function showChatRooms($user_id)
{
	return $this->connection->fetchAll('SELECT * FROM chat_rooms JOIN chat_permissions ON chat_rooms.id = chat_id WHERE user_id = ?', $user_id);
}

To znamená, že tohohle přesně bych chtěl dosáhnout zápisem pro Database Explorer.

ForestCZE
Člen | 209
+
0
-

@DavidMatějka

Funguje mi:

->select(':chat_permissions.chat_id')

což mi moc hlava nebere.

A co když potřebuji připojit tabulky dvě? Nějak takto:

$this->connection->fetchAll('SELECT * FROM chat_rooms JOIN chat_permissions ON chat_rooms.id = chat_id JOIN users ON author = users.id);
David Matějka
Moderator | 6445
+
0
-

při použití NDB explorer bys měl data většinou vybírat pouze z jedné tabulky a relace načítat přes ref nebo related. jiné tabulky se připojují hlavně pro filtrování.
když chci tedy vybrat autora, použiji

foreach ($context->table('chat_rooms') as $room) {
	$room->ref('author')->name;
}

pokud bys to chtěl vybrat v jednom dotazu, tak něco jako

$context->table('chat_rooms')->select('chat_rooms.author.name')