Je suis en train de créer une petite application Laravel
dans laquelle je souhaite afficher des versions spécifiques regroupées par mois. Quelque chose comme ceci:
@foreach ($releases as $release) <div> <p> <span>{{ \Carbon\Carbon::parse($release->release_date)->format('d. M')}}</span> <span>{{$release->artist}} - {{$release->album_title}} </span> </p> </div> @endforeach
Donc, dans mon contrôleur, je fais juste ceci:
public function index() { $releases = Release::orderBy('release_date', 'asc')->get(); return view('pages.index')->with('releases', $releases); }
Et dans mon fichier de vue en lame, je loppe le data:
January 11.1 - blabla more blablabla the same day 15.1 - blablabla February 05.2 - blabla etc...
Cela me donne les données correctes, par exemple une liste des entrées de base de données, mais comme mentionné précédemment, je veux les regrouper par mois et ajouter en plus un en-tête pour chaque mois. Comment puis-je y parvenir?
J'utilise Laravel 5.5
si cela compte ...
8 Réponses :
UNION ALL est le meilleur moyen de regrouper les données d'en-tête et de date en mois
Vous pouvez utiliser la méthode Collection :: groupBy () comme ceci:
[ "January" => Collection{Release, Release, Release}, "February" => Collection{Release, Release, Release}, ... ]
Maintenant $ releases est Collection avec le nom du mois comme clé et Collection (tableau de Releases ) comme valeur comme celle-ci:
$releases->groupBy(function(Release $release) { return $release->release_date->format('F'); });
N'oubliez pas les années;)
Si vous utilisez la méthode -> get () -> groupBy ('release_date'), elle renvoie les objets par date.
Par exemple;
public function index() { $releases = Release::orderBy('release_date', 'asc')->get()->groupBy('release_date'); return view('pages.index')->with('releases', $releases); }
Je pense résoudre votre problème.
public function index() { $releases = Release::orderBy('release_date', 'asc') ->get()->groupBy('release_date.month'); return view('pages.index')->with('releases_groups', $releases); } @foreach ($releases_groups as $month => $releases_group) // just place group info here... @foreach ($releases_group as $release) <div> <p> <span>{{ \Carbon\Carbon::parse($release->release_date)->format('d. M')}}</span> <span>{{$release->artist}} - {{$release->album_title}} </span> </p> </div> @endforeach @endforeach Try this.
La clé est groupBy ('release_date.month')
hmm, j'obtiens Colonne introuvable
en essayant ceci: - /
Je l'avais corrigé, placez -> groupBy ('release_date.month')
après get ()
, et tout ira bien.
ah je vois mais hmm ... je ne tire pas le nom des mois de ça ...: s
Ouais, j'avais édité le code, la clé de collection est month
, et c'est un entier de 1 ~ 12
, mais je ne sais pas si ce format est ce que vous vouloir.
Tous les formats disponibles sont month
, localeMonth
, shortLocaleMonth
, englishMonth
, shortEnglishMonth
, vous peut essayer et voir ce que tu veux
Ah alors comment puis-je faire sortir les informations du groupe?
@foreach ($ releases_groups as $ month => $ releases_group)
, le $ month
est la seule information de groupe à ce jour, hmm, n'est-ce pas suffisant?
ah mon mauvais, je viens de le voir :-) Alors maintenant, je dois juste comparer la valeur entière et renvoyer la chaîne correcte comme 1 = janvier, 2 = février, etc.?
Vous n'avez pas besoin de faire cela, utilisez plutôt un format différent, par exemple, -> groupBy ('release_date.englishMonth')
, le $ month
serait 'January ',' Février ', etc. Tous les formats de mois disponibles ont déjà été répertoriés
Après avoir examiné les autres réponses, une chose importante que vous devez savoir est que groupBy
est utilisé pour regrouper votre ensemble de résultats. Cela signifie que si vous utilisez paginer
au lieu de get
, le même mois de la vie réelle peut ne pas être groupé correctement.
Je suggère que votre contrôleur fasse plus de travail:
// For each release date first @foreach ($releaseDates as $releaseDate) <div> <p> //Print out the date as requested <span>{{ \Carbon\Carbon::parse($releaseDate->Date)->format('d. M')}}</span> // Now loop through each record nested as an array inside the date @foreach($releaseDate['data'] as $data) <span>{{$data->artist}} - {{$data->album_title}} </span> <br> @endforeach </p> </div> @endforeach
Ensuite, à votre avis:
public function index() { // Here we get a distinct list of dates in your format $releaseDates = Release::Selectraw('date_format(date(release_date),"%d.%m") as Date')->distinct()->get(); // For each date we now get the elements for each date and put them as an array entry in to the date under a 'data' section foreach($releaseDates as $releaseDate){ $releaseDate['data'] = Release::whereraw('date_format(date(release_date),"%d.%m") = '.$releaseDate->Date)->get(); } // Pass the data to the view as before but with new name return view('pages.index')->with('releaseDates', $releaseDates ); }
Maintenant, chaque entrée a la même date :-)
@ ST80 J'ai ajouté quelques commentaires, notez la deuxième boucle foreach dans votre vue en lame maintenant qui est nécessaire pour extraire les enregistrements sous chaque date.
Qu'en est-il de quelque chose comme ça (dans votre contrôleur)?
$groupedReleases = null; foreach ($releases as $release) { $date = $release->release_date->format('your desired format'); $groupedReleases[$date][] = $release; } return $groupedReleases;
Vous pouvez le faire comme ceci:
Tableau: versions
@foreach($month_headers as $header) {{getMonthName($header->month)." (".$header->header.")"}} <ul> @foreach($month_headers->releases() as $release) <li>{{date('d.m', strtotime($release->released_at))." - ".$release->bla_details}}</li> @endforeach </ul> @endforeach
Tableau: en-têtes_mois p>
public function temp() { $response['month_headers'] = MonthHeader::all(); return view('tempView', $response); }
Modèle: Release.php
public function releases() { return $this->hasMany('App\Models\Release'); }
Modèle: MonthHeader.php strong>
public function month_header() { return $this->belongsTo('App\Models\Month'); }
Aide: getMonthName ($ integer)
Controller: TempController.php
id | month(specific length int) | year(specific length int) | header
Affichage de la lame: tempView.blade.php
id | released_at | bla_details | month_header_id
Afficher la sortie
Janvier (en-tête de janvier)
Février (en-tête de février)
etc...
Explication ajoutée.
Très belle solution aussi! :-)
Voir la fonction de sélection ci-dessous avec une requête brute où j'ai ajouté "Nom du mois" et "numéro du mois" pour votre référence. Veuillez vérifier la sortie. J'espère que cela vous aidera
$releaseArray=[]; if(!empty($releases)) { foreach($releases as $release){ $releaseArray[$release->month][] = $release; } } print_r($releaseArray);Vous pouvez utiliser GroupBy si vous êtes sûr qu'il n'y a pas plus d'une version à la même date.
$releases = Release::select(DB::raw('some_field, MONTHNAME(release_date) as month_name, MONTHNAME(release_date) as month')) ->orderBy('release_date', 'asc')->get();Vous pouvez maintenant passer le $ releaseArray à la vue et itérer pour les versions regroupées par mois.