nette database nefunkční join

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

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

enumag
Člen | 2118
+
0
-

Ukaž strukturu DB a rozveď „nefunguje“.

Miri
Člen | 117
+
0
-

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)

enumag
Člen | 2118
+
0
-
  1. Používej /--code, tohle se čte dost špatně. Opravil bych to sám, ale nemám oprávnění.
  2. Máš dost podivnou konvenci pojmenovávání tabulek a sloupců.
  3. Když vybíráš z tabulky texty tak kam bys chtěl joinovat když ta tabulka nemá žádný cizí klíč?
Miri
Člen | 117
+
0
-
  1. použil jsem inline kod (asi nebylo nejlepší řešení)
  2. je to moje starší česká konvence a teď už se mi s tím nechce moc hýbat.
  3. 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

enumag
Člen | 2118
+
0
-

Jdeš na to opačným směrem. Pokud jsem tě správně pochopil tak takhle:

$this->connection->table('menu_has_texty')
	->where("texty_idtexty.zobrazovat", 1)
	->where('menu_idmenu', $idmenu);

Editoval enumag (18. 6. 2013 10:53)

Miri
Člen | 117
+
0
-

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

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

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

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.

enumag
Člen | 2118
+
0
-

Nejlepší zdroj jsou imho slajdy z přednášky.

Pokud jde o konvence tak používám tytéž jako @hrach v těch slajdech.

Editoval enumag (18. 6. 2013 11:46)