Laravel:Eloquentで1対多リレーションの@foreachで子テーブルの指定カラムで並び替えしたい

Laravel:Eloquentで1対多リレーションの@foreachで子テーブルの指定カラムで並び替えしたい

やり方について少し悩んだので備忘録です。

現在、作成したシステムのマニュアルを作成しているのですが、HTMLを書くのはとても面倒なので「DBに書いて呼び出してHTML合成する」そんな形にしています。

その中で、JOIN先の値を並び替えて取りたいときがありました。

そんな時の対応方法です。

普通にやると子テーブル側はIDの順に取れる

#table:manuals
Schema::create('manuals', function (Blueprint $table) {
    $table->increments('id');
    $table->string('title')->comment('タイトル');
    $table->unsignedInteger('selecter_id')->nullable()->comment('分類');
    $table->integer('sortnumber')->comment('並び順');
    $table->integer('manualsentence_id')->comment('マニュアル構成パーツID');
    $table->softDeletes();
    $table->timestamps();
    });

#table:manualsources
Schema::create('manualsources', function (Blueprint $table) {
    $table->increments('id');
    $table->string('subtitle')->comment('サブタイトル');
    $table->unsignedInteger('manual_id')->nullable()->comment('親ID');
    $table->integer('sortnumber')->comment('並び順');
    $table->softDeletes();
    $table->timestamps();
    });

これをViewで取り出すとき、こんな感じで書くと取り出される $souce->subtitle は manualsources->idの順になっています。

#manualController.editでManualの抽出

 $item = Manual::find($id);
#viewで$itemからmanualsourceを取り出す

@foreach($item->manualsouce as $souce)
  {{$souce->subtitle}}
@endoforeach

子テーブルのsortnumberで並び替えて取得するときはひと手間必要

@foreach の際にorderbyを付け加えてget() したものを foreach するように指示が出来ます。

@if(!empty($item->manualsouce))
  @foreach($item->manualsouce()->orderBy('sortnumber','asc')->get() as $souce)
    {{souce->subtitle}}
  @endforeach
@endif

これで、想定した動き(子テーブルのsortnumber 順)に取得が可能となります。

ついでにもう一つ

@if(!empty ()) + @foreach() を @forelse に置き換える

@forelse($item->manualsouce()->orderBy('sortnumber','asc')->get() as $souce)
  <h4>{{$souce->subtitle}}</h4>
@empty
   ~~作成中~~
@endforelse

注意点は@emptyの指定が必須である事。値が無くても@emptyを配置していないとエラーが出ます。

まとめ

@forelse、知らなかった。

ここまでif+foreach で書いてきたので「結構悠長な書き方してたんだなぁ~」と見直してみたい気分にもなりますが、まずは公開まで持ってかないとです。

見直し時のチェックポイントとしてメモしておきました。

プログラミングの面白さでもありますが、思った事をやる方法が必ず見つかるってのがうれしいですよね。

さぁ頑張ろ。

\ 最新情報をチェック /

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください