Laravelでフォームのデータを処理する(2/2)DBのデータをトップページに表示する


はじめに

この記事はLaravelでフォームのデータを処理する(1/2)フォームで送信されたデータを取得しDBに挿入するの続きです。

今、掲示板のようなWebサービスを作成していて、Laravelで下記のような機能を実装したいです。
(1)フォームで送信されたデータを取得し、DBにデータとして挿入する。
(2)DBのデータをトップページに並べて表示する。

こんな初歩的な機能ですが、頭を抱えまくったのでメモしておきます。Laravelでこれを実現するには、色々な方法があるみたいですが、初心者の時速40kmの走行方法(教習所内)をメモしておきたいと思います。今回は(2)を実装していきます。

環境:Laravel 7、MAMP 5.7
MAMP以外をご利用の方はそこだけ貴方の環境に合わせて変換していただければと思います。

1)DBにデータが入っていることを確認する

言わずもがなですが、DBが空だと何も表示できないので、ダミーでいいのでデータを入れます。

2)トップページを用意し、プログラムを埋め込む

今回はBladeテンプレートを使用し、/resources/views直下に置いています。。(非常に簡略化しています)
例はライブの感想を投稿する掲示板なので、ライブの日付(live_date)や、ミュージシャン(musician)、会場(venue)、感想(text)などを表示したいです。

index.blade.php
    <div>
     @foreach ($items as $item)
       <p>{{$item->live_date}}</p>
       <p>{{$item->musician}}</p>
       <p>{{$item->venue}}</p>
       <p>{{$item->text}}</p>
     @endforeach
    </div>

ポイント↑:

  • いきなり{{$item->live_date}}みたいなプログラムを埋め込んでしまっていますが、最初は普通にHTMLだけで静的なサイトを準備して、ダミーでデータも書き込んでおいて、あとでその部分をプログラムで書き換えるのがいいと思います。
  • @はディレクティブと呼ばれ、Blade内でここに構文(ifなど)的なプログラムを書くよーという合図です。
  • foreachで$itemsという配列変数を受け取り、それを$itemとして一つずつ抜き出していきます。
  • その$itemは{{$item->live_date}}で使用されます。
  • が、ここに$itemsという変数を渡して上げないといけません。それが次のコントローラの役割です。

3)コントローラ

2で作ったページに渡す変数を定義し、そのページ自体を返すという設定をします。第1話で作ったControllerで、/app/Http/Controllersフォルダに配置しています。

PostController
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use Illuminate\Support\Facades\DB; //DB接続のクラス

class PostController extends Controller
{
    //こちらを追加
    public function index(Request $request)
    {
        $items = DB::select('select * from reviews');
        return view('index', ['items' => $items]);
    }

ポイント↑:

  • DB::selectでDBの全てのデータ*を呼び出し、index.blade.phpに渡す変数$itemsに代入します。
  • Viewsフォルダ直下にあるindex(.blade.php)を呼び出し、第二パラメータでitemsという名前で、$itemsの値をindex(.blade.php)に渡してねと指示しています。この'items'がview(index.blade.php)内の$itemsと値が一致していないときちんとリンクしません。$のあるなしでややこしいことになっていますが...
  • あとはこのコントローラとアクションメソッドを呼び出す設定をしてあげればよくて、それをRoutingで行います。

4)ルーティング

web.php
<?php

use Illuminate\Support\Facades\Route; //デフォルトで書いてあるクラス

Route::get('/', 'PostController@index'); //こちらを追加

ポイント↑:

  • 第1パラメータは'/'、つまり、トップページ(=Document Rootを設定しているアドレス)にアクセスがあったらという条件設定
  • 第2パラメータ、PostControllerを呼び出し、そこにあるindexメソッドアクションを、、
  • 呼び起こしなさい(=Route::get)という命令文

5)成功

この状態でドキュメントルートに設定しているページにアクセスすると、DBの情報が存在しているだけ全てトップページに表示されるはずです。

うまく行かない場合のヒント

  • 私は当初、ルーティングのRoute::getをRoute::postにするという、ブレーキとアクセスを踏み間違えるようなミスで、エラーを起こしていました。
  • $items$itemなどの複数形のsのあるなし、$の付け忘れ、その他スペルミスはないか。

最後に

もし何かご指摘などありましたら、コメント欄などで頂戴できますと幸いです。