nette database nefunkční join
- Miri
- Člen | 117
Ahoj, prosím o pomoc, napsal jsem toto:
public function getTextsByMenu(){
$row = $this->connection->table('texty')->where("zobrazovat = 1");
foreach ($row as $item){
$item['textynazev'] = $item->related('textynazev')->where("jazyk_idjazyk", 1)->fetch();
}
return $row;
}
Což mi vybere všechny texty z databáze a pak k nim vybere textynazev podle jazyka. Toto mi funguje dobře, ale když se snažím texty vybrat podle aktuálního menu takto:
public function getTextsByMenu($idmenu){
$row = $this->connection->table('texty')->where("menu_has_texty.menu_idmenu = ?",$idmenu)->where("zobrazovat = 1");
foreach ($row as $item){
$item['textynazev'] = $item->related('textynazev')->where("jazyk_idjazyk", 1)->fetch();
}
return $row;
}
Tak již nefunguje. Nevíte jak na to?
Předem díky za jakoukoliv radu
Míra
- Miri
- Člen | 117
Tohle mi vypisuje laděnka :
`Nette\Database\Reflection\MissingReferenceException
No reference found for $texty->menu_has_texty.`
Tady je zjednoduešená struktura struktura.
CREATE TABLE IF NOT EXISTS `mydb`.`menu` (
`idmenu` INT NOT NULL AUTO_INCREMENT ,
`zobrazovat` TINYINT(1) NULL ,
`typ` INT NULL ,
PRIMARY KEY (`idmenu`) )
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `mydb`.`menunazev`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`menunazev` (
`idmenunazev` INT NOT NULL AUTO_INCREMENT ,
`menu_idmenu` INT NOT NULL ,
`nazev` VARCHAR(45) NULL ,
`jazyk_idjazyk` INT NULL ,
PRIMARY KEY (`idmenunazev`) ,
INDEX `fk_menunazev_menu` (`menu_idmenu` ASC) ,
CONSTRAINT `fk_menunazev_menu`
FOREIGN KEY (`menu_idmenu` )
REFERENCES `mydb`.`menu` (`idmenu` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `mydb`.`texty`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`texty` (
`idtexty` INT NOT NULL AUTO_INCREMENT ,
`zobrazovat` INT NULL ,
PRIMARY KEY (`idtexty`) )
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `mydb`.`textynazev`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`textynazev` (
`idtextynazev` INT NOT NULL AUTO_INCREMENT ,
`nazev` VARCHAR(45) NULL ,
`popis` TEXT NULL ,
`jazyk_idjazyk` INT NULL ,
`texty_idtexty` INT NOT NULL ,
PRIMARY KEY (`idtextynazev`) ,
INDEX `fk_textynazev_texty1` (`texty_idtexty` ASC) ,
CONSTRAINT `fk_textynazev_texty1`
FOREIGN KEY (`texty_idtexty` )
REFERENCES `mydb`.`texty` (`idtexty` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `mydb`.`menu_has_texty`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`menu_has_texty` (
`menu_idmenu` INT NOT NULL ,
`texty_idtexty` INT NOT NULL ,
PRIMARY KEY (`menu_idmenu`, `texty_idtexty`) ,
INDEX `fk_menu_has_texty_menu1` (`menu_idmenu` ASC) ,
INDEX `fk_menu_has_texty_texty1` (`texty_idtexty` ASC) ,
CONSTRAINT `fk_menu_has_texty_menu1`
FOREIGN KEY (`menu_idmenu` )
REFERENCES `mydb`.`menu` (`idmenu` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_menu_has_texty_texty1`
FOREIGN KEY (`texty_idtexty` )
REFERENCES `mydb`.`texty` (`idtexty` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
Editoval Miri (18. 6. 2013 10:33)
- Miri
- Člen | 117
- použil jsem inline kod (asi nebylo nejlepší řešení)
- je to moje starší česká konvence a teď už se mi s tím nechce moc hýbat.
- Tabulka texty je rodič tabulek ‚menu_has_texty‘ a ‚textynazev‘ Mojí snahou je vybrat podle menu_idmenu v tabulce ‚menu_has_texty‘ všechny texty, ktere se mají ‚zobrazovat=1‘ a k nim přiřadit textynazev s jazyk_idjazyk = 1
Bohužel vůbec nevím jestli na to jdu správným způsobem
- Miri
- Člen | 117
Tady jsem nastínil obyčejný query dotaz, mohlo by být pochopitelnější.
$row = $this->connection->query('
SELECT
idtexty, textynazev.popis
FROM
texty
JOIN
menu_has_texty on menu_has_texty.texty_idtexty = texty.idtexty and menu_has_texty.menu_idmenu = '.$idmenu.'
LEFT JOIN
textynazev on textynazev.texty_idtexty = texty.idtexty and textynazev.jazyk_idjazyk = 1');
return $row;
- Miri
- Člen | 117
Super, tohle už funguje.
$this->connection->table('menu_has_texty')
->where("texty_idtexty.zobrazovat", 1)
->where('menu_idmenu', $idmenu);
Bohužel nevím jak do toho zapojit ještě tabulka textynazev
Zkoušel jsem to takto, ale neúspěšně.
$row = $this->connection->table('menu_has_texty')->where("texty_idtexty.zobrazovat", 1)->where('menu_idmenu', $idmenu);
foreach ($row as $item){
$item['textynazev'] = $item->related('textynazev')->where("jazyk_idjazyk", 1)->fetch();
}
return $row;
- enumag
- Člen | 2118
Snad takhle.
foreach ($row as $item) {
$item['textynazev'] = $item->ref('texty_idtexty')->related('textynazev')->where("jazyk_idjazyk", 1)->fetch();
}
Ale vážně doporučuji lepší konvence pojmenování. V tomhle se nedá vyznat a každej dotaz bys sestavoval hodinu.
Editoval enumag (18. 6. 2013 11:21)
- Miri
- Člen | 117
Super funguje, no mám to už docela v hlavě, takže mi to nedělá
problémy v normálním query sestavovat. A když už jsme v tom jakou
konvenci bys doporučil? Sice pomalu měním, ale jestli je to ta ideální to
taky nevím.
a ještě jedna otázka, je někde pěkně sepsáno co vlastně dělá to ref a
related a nějakých pár ukázkových příkladů?
Každopádně mockrát díky za pomoc.