IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Diskuze: laravel "předchozí díl"

V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
Martin Suchodol:15.5.2020 11:19

Ahoj, učím se slaravel a tak si zkouším vytvořit různé funkce. Do zdejšího seriálu na redkční systém. Aktuálně se pokouším o něco jako je funkce seriálu. Takže abych to shrnul:

  • při vytváření článku si ze seznamu článků vyberu již existující článek na který chci navázat, ano vím že tento způsb je neideální. Pokud by to mělo reálně fungovat a bylo tam třeba 1000 článků tak se při hledání zblázním.
  • do databáze se uloží ID článku na který chci navázat, ukládám do stejné tabulky jako článek, opět vím že to není vhodné, a ideálně bych měl mít samostatnout tabulku, abych si pak mohl zobrazit jen články z daného seriálu, nebo mohl zobrazovat i následující články v seriálu.
  • Při následné editaci vše funguje jak má. Včetně toho že se mi načte i název přechozího článku

Ale to s čím bojuji je jak do pohledu pak vepsat odkaz na přechozí díl, pokud existuje. Takže jsem zkoušel následující:

Zkusil jsem:

@if ($article->previous_part_id !== null){
<div class="previous_part">
    <i class="fas fa-arrow-circle-left"></i>
    <p>Předchozí díl</p>
    @php
        $articl = $article::find($article->previous_part_id);
    @endphp
        <a href="{{ url("article/" . $articl->url) }}">{{ $articl->title }}</a>
    }

</div>
@endif

Na první pohled to funguje, zobrazí se odkaz. A odkaz směřuje na předchozí článek. Ovšem problém je ve chvíli kdy se pokusím na odkaz kliknout. Tak dostanu vyhubováno.

Trying to get property 'url' of non-object
 
Odpovědět
15.5.2020 11:19
Avatar
Neaktivní uživatel:15.5.2020 13:12

Ahoj, tahle pasáž je nějaká divná.

$article::find(...)

Proměnná $article je výstupem dřívějšího dotazu a skoro určitě nejde o třídu se statickou metodou find. Podle mého jsi chtěl zavolat Laravel model, čili bych čekal něco jako.

$articl = Article::find($article->previous_part_id)->first();

Výpis bys měl ošetřit podmínkou. Ovšem ne podle toho, že tvůj článek obsahuje previous_part_id (tím řeš pouze to, zda se budeš dotazovat do DB), ale až podle toho, že jsi předchozí článek v DB našel.

$articl = Article::find($article->previous_part_id)->first();
@if ($articl !== null)
  <div class="previous_part">
  ...
  <a href="{{ url("article/" . $articl->url) }}">{{ $articl->title }}</a>
  ...
  </div>
@endif

Jestli Ti můžu poradit, zaměř se při tom učení taky na to, jak si podobné dotazy vyřešit v Controlleru a nedávej je do šablony. Jinak Laravel má velmi dobrou dokumentaci, tak ji využij a podívej se na modely a blade šablony včetně if statements, protože tam máš další chybu v použití závorek, které do blade nepatří a ještě je máš i špatně ukončené, že by Ti zůstal jeden konec DIVu navíc.

Nahoru Odpovědět
15.5.2020 13:12
Neaktivní uživatelský účet
Avatar
Odpovídá na Neaktivní uživatel
Martin Suchodol:15.5.2020 13:30

Určit na to mrknu, ale každopádně když jsem zkusil to co jsi mi poslal tak mám nový problém

Call to a member function first() on null
 
Nahoru Odpovědět
15.5.2020 13:30
Avatar
Jan Lupčík
Tvůrce
Avatar
Odpovídá na Martin Suchodol
Jan Lupčík:15.5.2020 13:35

Ahoj, rozhodně bych doporučoval získávat data v kontroleru a ne v pohledu. Pohled má jen zobrazovat data, které dostane od kontroleru :)
Každopádně k tvému problému: find() nic nenašel (= null), proto ani first() nelze použít. Na find() by se ani first() nemělo používat, jelikož výsledkem je rovnou model, ne kolekce.
Navíc by bylo vhodné tohle převést do vztahu, abys to nemusel nijak složitě získávat. Nevím, u jaké lekce aktuálně jsi, probírá se to dále v seriálu.

Nahoru Odpovědět
15.5.2020 13:35
TruckersMP vývojář
Avatar
Odpovídá na Jan Lupčík
Neaktivní uživatel:15.5.2020 13:47

Ahoj, máš pravdu, k find() už first() nepatří. Moje chyba.

Nahoru Odpovědět
15.5.2020 13:47
Neaktivní uživatelský účet
Avatar
Odpovídá na Jan Lupčík
Martin Suchodol:15.5.2020 15:26

Mám ho za sebou, ale procházím si to znovu. Kvůli některým věcem. Každopádně mě nenapadlo že by to šlo vyřešit i pomocí vztahu.

 
Nahoru Odpovědět
15.5.2020 15:26
Avatar
Odpovídá na Jan Lupčík
Martin Suchodol:20.5.2020 7:39

Tak asi budu potřebovat lehce nakopnout a to s výpisem. Takže co mám, resp. co jsem udělal.

Rozhodl jsem se pro vztah takže to řeším eloquent vztahem hasOne. Vztah řeším v rámci jedné tabulky.

Vztahy jsem doplnil takto:

public function serial()
{
    return $this->hasOne('article', 'previous_part_id');
}

public function article() {
    return $this->belongsTo('article', 'previous_part_id');
}

První pokus o výpis skončil chybou: Class 'article' not found

return view('article.show', ['article' => $article, 'previous' => Article::find(1)->serial]);

Druhý pokus mi vyhodil stejnou chybu. Zde jsem se o výpis pokusil již v show.blade.php bez deklarace proměnné

{{ $article->serial->previous_part_id }}
//Zkoušel jsem i variantu
{{ $article->article->previous_part_id }}
Editováno 20.5.2020 7:39
 
Nahoru Odpovědět
20.5.2020 7:39
Avatar
Jan Lupčík
Tvůrce
Avatar
Odpovídá na Martin Suchodol
Jan Lupčík:20.5.2020 12:26

Ve vztahu se definuje odkaz na třídu. Ty jsi pouze předal textový řetězec "article". Proto ti to správně vyhazuje chybu, že třída article nebyla nalezena. Správné možnosti tedy jsou:

public function previous()
{
    return $this->hasOne('App\Article', 'previous_part_id');
}

Nebo druhá možnost, kterou preferuji více:

public function previous()
{
    return $this->hasOne(static::class, 'previous_part_id'); // normálně by to bylo Article::class, ale jelikož se jedná o stejnou třídu, lze použít static::class
}
Nahoru Odpovědět
20.5.2020 12:26
TruckersMP vývojář
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 8 zpráv z 8.