Autor Zpráva
KarelEben
Profil
Zdravím,
mohl by PROSÍM někdo pomoci?
mám databázi:
CREATE TABLE `soubory` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `text` varchar(250) NOT NULL,
  `url` varchar(250) NOT NULL,
  `imgurl` varchar(500) NOT NULL,
  `datum` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `soubory` (`id`, `text`, `url`, `imgurl`, `datum`) VALUES
(1,   'Neco', 'http://www.randpm.cz/zprava13_14.pdf',    'http://www.randpm.cz/images/link_pdf.png',    '2015-01-27 09:55:17'),
(2,   'Peni', 'http://www.randpm.cz/dwnl/2013_14/zprava13%20.pdf',    'http://www.randpm.cz/images/link_pdf.png',    '0000-00-00 00:00:00');

CREATE TABLE `stranky` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nadpis` varchar(250) NOT NULL,
  `datum` datetime NOT NULL,
  `obsah` longtext NOT NULL,
  `url` varchar(250) NOT NULL,
  `uzivatel_id` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `uzivatel_id` (`uzivatel_id`),
  CONSTRAINT `stranky_ibfk_1` FOREIGN KEY (`uzivatel_id`) REFERENCES `uzivatel` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `stranky` (`id`, `nadpis`, `datum`, `obsah`, `url`, `uzivatel_id`) VALUES
(4,    'Výroční zpráva',    '2015-01-27 09:54:08',    'Blah blah Blah',    'vyrocni-zprava',    1);

CREATE TABLE `stranky_has_soubory` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `stranky_id` int(11) NOT NULL,
  `soubory_id` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `stranky_id` (`stranky_id`),
  KEY `soubory_id` (`soubory_id`),
  CONSTRAINT `stranky_has_soubory_ibfk_1` FOREIGN KEY (`stranky_id`) REFERENCES `stranky` (`id`),
  CONSTRAINT `stranky_has_soubory_ibfk_2` FOREIGN KEY (`soubory_id`) REFERENCES `soubory` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `stranky_has_soubory` (`id`, `stranky_id`, `soubory_id`) VALUES
(1,    4,    1),
(2,    4,    2);


Potřebuji získat seznam souborů kde je id stránky "vyrocni-zprava"
$zpravy = $this->database
                ->table("stranky")
                ->where("url", "vyrocni-zprava")
                ->related("stranky_has_soubory");
$this->template->zprava = $zpravy;
atd...
potřebuji potom nad tím dělat něco takového:
Seznam přidružených souborů k strance s url "vyrocni-zprava"
<tr n:foreach="$zpravy as $zprava">
            <td>{$zprava->text}</td>
            <td><a href="{$zprava->url|noescape}"><img src="{$zprava->imgurl}" alt="{$zprava->text}" /></a></td>
        </tr>
Text co je v tabulce stranka v sloupic obsah
{$text->obsah}
Keeehi
Profil
1) Víš že nette má své fórum? Tam je větší šance že budou lidé, kteří ti poradí. I když tady jsou samozřejmě také lidé toho schopní.
2) Opravdu potřebuješ M:N vazbu? Podle toho "obsahu" se mi zdá že možná soubor bude patřeit maximálně k jedné stránce. Pokud ano, vše by se zjednodušilo.
3) Název tabulky stranky_has_soubory mě opravdu pobavil. Když už to pojmenovávš česky, tak prosím všechno. A nejlépe vše pojmenovávej anglicky, budeš mít v budoucnu méně problémů.
4) je to nějak takto:
$zpravy = $this->database
                ->table("stranky")
                ->where("url", "vyrocni-zprava");
$this->template->zprava = $zpravy;

<tr n:foreach="$zpravy as $zprava">
    <td>{$zprava->text}</td>
    <td><a href="{$zprava->url|noescape}"><img src="{$zprava->imgurl}" alt="{$zprava->text}" /></a></td>
    <td n:inner-foreach="$zprava->related('stranky_has_soubory') as $connectionToSoubor">
        {$connectionToSoubor->ref('soubory', 'soubory_id')->text}
        {$connectionToSoubor->ref('soubory')->text}
        {$connectionToSoubor->soubory->text}
    </td>
</tr>

řádky 5, 6 a 7 jsou ekvivalentní. Stejně jako:
$zprava->related('stranky_has_soubory', 'stranky_id')
$zprava->related('stranky_has_soubory.stranky_id')
$zprava->related('stranky_has_soubory')
KarelEben
Profil
Keeehi:
1) Ano vím, ale tady je to aktivnější takže člověk dostane odpověd rychleji.
2) Přemýšlel jsem dopředu že daný soubor muže být u více stránek, ale hodil by se mi teda ten kod kdybych teda to udělal v relaci 1:N.
3) ano jsem si toho vědom že mám v tom guláš, bohužél jsem na to zapoměl a ted už je pozdě
4) bohužel nefunguje, skouším upravit


Tak po mírných úpravách lze takhle řešit
{foreach $zpravy as $zprava}
           {foreach $zprava->related('stranky_has_soubory') as $connectionToSoubor}
                <tr>
                    <td>
                        {$connectionToSoubor->ref('soubory', 'soubory_id')->text}
                    </td>
                    <td>
                        <a href="{$connectionToSoubor->ref('soubory', 'soubory_id')->url|noescape}"><img src="{$connectionToSoubor->ref('soubory', 'soubory_id')->imgurl|noescape}" alt="{$connectionToSoubor->ref('soubory', 'soubory_id')->text}" /></a>
                    </td>
                </tr>
            {/foreach}
        {/foreach}


$zpravy = $this->database
                ->table("stranky")
                ->where("url", "vyrocni-zprava");
        $this->template->zpravy = $zpravy;
Keeehi
Profil
Jo omlouvám se, co je v rámci toho odkazu jsem nekonroloval a jen to hloupě zkopíroval. Hlavně že to funguje.

3) Nikdy není pozdě. Vlastně čim dříve tím lépe. Přepište to než toho kódu budete mít více. A když už v tom budete sjednoťte si pojmenování stránky a zprávy.

Pro 1:N by byly jen tabulky soubory a stranky. Stranky by zůstala a do souborů by se přidal sloupec stranky_id, vazební tabulka pryč
$zpravy = $this->database
                ->table("stranky")
                ->where("url", "vyrocni-zprava");
// dostupné jsou teď $zpravy->url $zpravy->obsah $zpravy->datum atd.

foreach ($zpravy->related('soubory') as $soubor) {
    // dostupné jsou teď $soubor->imgurl $soubor->text $soubor->datum
}
KarelEben
Profil
Keeehi:
Děkuji za rady. Jdu přepisovat. Uzamykám :)
Moderátor Joker: Odemčeno, tady se po odpovědi nezamyká.
KarelEben
Profil
Keeehi:
Omlouvám se že ruším ale hází mi to chybu:
Nette\MemberAccessException

Call to undefined method Nette\Database\Table\Selection::related().

Na řádku:
<?php $iterations = 0; foreach ($soubory->related('soubory') as $soubor) { ?>
Mohl bych ještě poprosit o pomoc?
Tu tabulku jsem teda předělal na 1:N

presenter:
$soubory = $this->database
                ->table("stranky")
                ->where("url", "vyrocni-zprava");
        
        $vyrocni_zprava = $this->database
                ->table("stranky")
                ->where("url", "vyrocni-zprava")
                ->fetch();
        
        $this->template->soubory = $soubory;
        $this->template->vyrocni_zprava = $vyrocni_zprava;

template:
{block content}
<p>
    {$vyrocni_zprava->obsah}
</p>
    <table>
        <tr>
            <td>Dokument</td>
            <td>Stáhnout</td>
        </tr>
           {foreach $soubory->related('soubory') as $soubor}
                <tr>
                    <td>
                        {$soubor->text}
                    </td>
                    <td>
                        <a href="{$soubor->url|noescape}"><img src="{$soubor->imgurl|noescape}" alt="{$soubor->text}" /></a>
                    </td>
                </tr>
            {/foreach}
    </table>
Keeehi
Profil
Smaže ->related('soubory') a bude to v pořádku.

Proč? Vy už přece v proměnné $soubory máte to co jste chtěl - tedy pole souborů pro danou stránku.
Funkce related a ref se používají pro získávání dodatečných dat.
Mám stánku v proměnné a potřebuji se dostat k jejím souborům: stránka -> related => soubory
Mám soubor v proměnné a potřebují se dostat k související stránce: soubor -> ref => stranka

Všimněte si, že v prvním případě dostáváme kolekci (něco jako pole) která obsahuje naše záznamy, kdežto v druhém případě dostávám už přímo ten jeden záznam.
KarelEben
Profil
Keeehi:
Nemám, do proměné $soubory přeci vlkádám
$soubory = $this->database
                ->table("stranky")
                ->where("url", "vyrocni-zprava");
$this->template->soubory = $soubory;
Keeehi
Profil
Máte pravdu. To vaše jiné pojmenování tebulek a proměnných je něco na co nejsem zvyklý a opravdu mě to mate.

V tom foreach nevolejte $soubory->related ale $vyrocni_zprava->related
related a ref se musejí volat nad je jedním řádkem z výsledku dotazu. Takže po fetch().

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0