Návrh tabuliek pre viacjazykový web + query
- NiNu
- Člen | 31
Zdravím,
potreboval by som poradiť. Robím si web kde by som chcel aj viacjazyčnú
podporu (en, sk). Na preklad šablóny a textov som použil komponentu
kdyby/translator a teraz ešte by som chcel vyriešiť aj preklad údajov
ťahaných z DB (zatiaľ to skúšam aplikovať len na novinky, ak by to išlo,
tak aj na zvyšok webu).
Chcel by som použiť nasledovnú štruktúru: 4. Additional Translation Table Approach
Takže mám vytvorené nasledujúce tabuľky:
CREATE TABLE `news` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(128) NOT NULL,
`body` text NOT NULL,
`date` datetime NOT NULL,
`users_id` int(11) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `users_id` (`users_id`),
CONSTRAINT `users_id` FOREIGN KEY (`users_id`) REFERENCES `users` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `languages` (
`code` char(2) NOT NULL,
`name` varchar(20) NOT NULL,
PRIMARY KEY (`code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `news_translation` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`news_id` int(11) unsigned NOT NULL,
`language_code` char(2) NOT NULL,
`title` varchar(128) NOT NULL,
`body` text NOT NULL,
PRIMARY KEY (`id`),
KEY `translation_id` (`news_id`),
KEY `language_code` (`language_code`),
CONSTRAINT `translation_id` FOREIGN KEY (`news_id`) REFERENCES `news` (`id`),
CONSTRAINT `language_code` FOREIGN KEY (`language_code`) REFERENCES `languages` (`code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Podľa príkladu by som mal vytvoriť asi nasledujúcu query na výber podľa jazyka:
$sql = "SELECT news.*, news_translation.title, news_translation.body
FROM `news` p
INNER JOIN `news_translation` ON news.id = news_translation.news_id
WHERE news.id = 1 AND news_translation.language_code = '$current_language'";
Zatiaľ som si spravil len malý test, či vlastne dokážem spraviť inner join. Takže som si vytiahol len jednu novinku a skúsil, či prepínaním jazykov to bude robiť to čo má. Nasledujúci kód mi funguje presne ako chcem:
public function newsOnLanguage($lang) {
return $this->database->table('news_translation')->where('language_code = ?', $lang)->where('news_id = news.id')->fetch();
}
Toto mi vyhodí nasledujúcu query v debugbare:
SELECT `news_translation`.`id`, `news_translation`.`title`, `news_translation`.`body`
FROM `news_translation`
INNER JOIN `news` ON `news_translation`.`news_id` = `news`.`id`
WHERE (`language_code` = ?) AND (`news_id` = `news`.`id`)
následne v presentri mam:
public function renderSingle() {
$this->template->myNews = $this->newsRepository->newsOnLanguage($this->translator->getLocale());
}
Avšak podľa toho príkladu vyššie by som to mal mať opačne, čiže vyberať tabuľku news a zvyšok z news_translation, ale opačne mi to nefunguje a taktiež mi nefunguje ani $myNews->users->username.
Potreboval by som poradiť ako by to celé malo vyzerať na základe toho
príkladu z linku vyššie, asi stačí len nejak správne zostaviť výber
z DB.
Ďakujem
Editoval NiNu (13. 12. 2013 21:57)
- Oli
- Člen | 1215
Ahoj,
nějak nechápu význam té tanulky news_translation. V ní i v news máš
title i body. Máš tam teda duplicitní informace.
Já to používám bez té jedné tabulky a mám teda:
news: id, title, body, date, …, language_id. S tím, že id+language_id jsou
unique
language: id, name
dotaz potom vypadá
$row = $this->db->table('news')->getPrimary(1);
$row->title;
$row->language->name;
PS. podle toho jak to máš v tom dotazu by mělo jít vytáhnout uživatele jako
$myNews->news->users->username;
- NiNu
- Člen | 31
Ano viem, že je tam tá duplicita, tú si nevšímajte, najskôr som chcel
vyskúšať, či to bude fungovať potom v news tie duplicity title a body
samozrejme vymažem, keďže tam už budú nepotrebné, no zatiaľ mi to
nefunguje tak ako chcem.
Snažím sa o tento návrh:

tabuľky aj s FK mám, už potrebujem len správne zostaviť not-orm query
- Oli
- Člen | 1215
Nejjedonuší řešení je něco jako
$row = $this->repository->table('app_product_translation')->where('product_id = ? && language_code = ?', $id, $langCode);
$row->title;
$row->product->price;
$row->language->name;
// ...
Jediné co si nejsem jistej je, s tím language_code jestli ho to bude umět takhle najít. Já vždy používal someFK_id.