Laravel controllers

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Jorn Reed

Jorn Reed

08/04/2019 23:54:53
Quote Anchor link
Ik ben nu een beetje bezig met het experimenteren met Laravel.
Een algemeen project lukt me wel, waar je bijvoorbeeld content kan toevoegen in de database. En het op een andere pagina tonen etc. Dit doe ik simpelweg door een Model, Migration en Controller aan te maken voor een specifieke pagina. Meestal maak ik gebruik van een Resource controller, wat inhoud dat het alle crud opties bevat voor een specifiek database item. Verder vraag ik me af wat de beste manier is om in een controller te werk te gaan als ik bijvoorbeeld meerdere items op een pagina wil tonen. Hiermee bedoel ik bijvoorbeeld dat de gebruiker crud opties heeft voor alle nieuwsberichten op een pagina. Maar ook voor bijvoorbeeld afbeeldingen die op de pagina gelooped worden. Het zijn wel aparte elementen die niks met elkaar te maken hebben. Hopelijk kan iemand me hiermee helpen (uitleggen) wat de beste manier is om verschillende database objecten in 1 controller te verwerken.
Gewijzigd op 08/04/2019 23:55:44 door Jorn Reed
 
PHP hulp

PHP hulp

19/06/2019 18:07:38
 
TJVB tvb

TJVB tvb

12/04/2019 15:12:45
Quote Anchor link
Hoi Jorn,

Hier een voorbeeld:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
<?php
class NewsController
{
    public function show(News $news)
    {

        $news->load('images');
        return view('news.show', ['news' => $news]);
    }
}

?>


Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
<?php
//news/show.blade.php content

<h1>{{$news->title}}</h1>
<
p>{{$news->content}}</p>
@
foreach($news->images as $image)
<
img src="{{route('images.show', $image->id)}}" />
@
endforeach
?>


Het is een beetje afhankelijk van je code, maar het is hierbij praktisch om je relaties op de modellen te defineren. (Zie: https://laravel.com/docs/5.8/eloquent-relationships )
Dan kun je ze benaderen vanuit je model. Het tonen van de afbeelding is onderdeel van een andere controller, daarvoor kun je dus rustig naar de bijbehorende route linken.

De load is hierbij niet perse nodig omdat het geen versnelling is aangezien je maar 1 model hebt. Wel kun je daarbij er ook voor kiezen om bijvoorbeeld te sorteren, dat is netter om in je controller te doen dan in je view. Je krijgt dan:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
<?php
$news
->load(['images' => function ($imageQuery) {
    $imageQuery->orderBy('position');
}]);

?>
 
Frank Nietbelangrijk

Frank Nietbelangrijk

14/04/2019 13:21:36
Quote Anchor link
Een gouden regel is om je Controller class zo slank mogelijk te houden. En dat is niet voor niets! Zoals je zelf al aangeeft heb je voor een pagina al gauw een lijstje met verschillende dingen nodig. Ga je die allemaal in je controller samenstellen dan wordt het al snel onoverzichtelijk. De controller moet daarom niets anders doen dan andere classen aanroepen om data te vergaren en dan alle data aan de view meegeven.

zoiets dus:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
<?php
$news
= $newsModel->getLatestNewsItems();
$images = $bannerModel->getImages();

return view('news.show', [
    'news' => $news,
    'images' => $images
]);
?>
 
Jorn Reed

Jorn Reed

14/04/2019 19:22:08
Quote Anchor link
Ik snap wat jullie bedoelen. Maar met m'n vraag bedoelde ik net even iets anders. Ik wil dat de gebruiker met 1 controller de mogelijkheid heeft om nieuwsberichten te plaatsen. Hierbij heeft de gebruiker de keuze om een stukje tekst te plaatsen, een video of een afbeelding. Dus dat de gebruiker zelf bepaald wat voor bericht het is. Graag wil ik dit in 1 controller/model en 1 database tabel kunnen verrichten omdat het anders zo'n zoek zooitje word.
Ik had zelf al wel aan een structuur gedacht in de html:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
   @foreach($posts as $post)
       @if($post->type == 'text')
       //tekst html
       @if($post->type == 'video')
       //iframe ofzo
       @if($post->type == 'image')
       //afbeelding
       @endif
   @endforeach
 
Frank Nietbelangrijk

Frank Nietbelangrijk

14/04/2019 22:14:08
Quote Anchor link
Je zou beter kunnen werken met een entity. Een entity is een class dat in jou geval één Nieuwsbericht bevat. Het zal properties hebben als $created, $title, $content, $image(s), $video(s), $author etc.

Deze entity kun je vervolgens een method geven met een naam als bijv. getType() welke dan gaat bepalen of het een video, afbeelding of text bevat of misschien wel een mix daarvan.

In je view zou je dan iets krijgen als:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
@foreach($newsitems as $newsitem)

  ...

  @if($newsitem->getType() == 'video')
    <video width="400" controls>
      <source src="{{ $newsitem->getVideoUrl() }}" type="video/mp4">
    </video>
  @endif

  ...

@endforeach


Heb je al een keer naar Doctrine ORM gekeken?
Gewijzigd op 14/04/2019 22:18:21 door Frank Nietbelangrijk
 
Jorn Reed

Jorn Reed

14/04/2019 22:18:19
Quote Anchor link
Heb ik daarmee gewoon de mogelijkheid om 3 verschillende dingen met 1 soort model in dezelfde database tabel op te kunnen slaan?
 
Frank Nietbelangrijk

Frank Nietbelangrijk

14/04/2019 22:25:51
Quote Anchor link
Ja. Je kunt gewoon kolommen aanmaken die niet verplicht zijn.

Doctrine ORM kan veel zaken voor je regelen.

- Je kunt met een commandline tool een entity aanmaken (welke je later in je editor weer gaat uitbouwen).
- Als je de entity hebt kan Doctrine de database tabel voor je aanmaken of wijzigen al dan niet met migrations
- Doctrine zet de records uit de database automatisch voor je in een entity/entities.
- Doctrine kan zelfs prima met relaties van andere tabellen werken
- Doctrine zet een entity ook zo weg in de database voor je

Toevoeging op 14/04/2019 22:37:47:

Dit artikel lijkt me wel aardig voor je: https://www.sitepoint.com/laravel-doctrine-best-of-both-worlds/
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.