laravel 7 でリソース コントローラを自動生成して CRUD のうちindex表示を実装する ~Laravel入門~

laravel
この記事は約22分で読めます。
スポンサーリンク

PHPのフレームワークLaravel で blog アプリを作成しながら、laravelの使い方を説明しています。

Laravelはバージョン7を使います。

仕様と手順は、以下の記事の通りです。

今回は、3. アプリ作成の【7 Blog機能作成】の2回目となります。

今回の学習ポイントは次のとおり。

7. Blog機能作成
        7.4. 投稿コントローラの作成
        7.5. 投稿一覧の表示機能作成

いろんな書き方はあるのですが、基本的であり、応用が利きそうな方法を使って作成していきます。

なお、前回まででモデルとマイグレーションファイルを作成しましたが、もしまだの方は、作成してから、またこちらに戻ってきてくださいね。

スポンサーリンク

投稿コントローラの作成と投稿一覧の表示機能の作成

投稿コントローラで投稿を操作する

今回作成するのはblogなので、記事を投稿したり、閲覧したりする機能を付けます。

そのために投稿コントローラを作って、投稿を操作します。

Laravelのコントローラには、リソースコントローラを作るオプションがあります。

これはコントローラの中でも、モデルを操作するのに特化したものです。

リソースコントローラを作って、一覧表示をさせるところまでを勉強しましょう。

CRUD操作とリソースについて

ほとんどのツールは、リソース(データ)に対して、次の4つの操作が可能です。

・作成(Create)
・読み出し(Read)
・更新(Update)
・削除(Delete)

この4つの操作は、頭文字をとって CRUD(クラッド)を呼ばれます。

今回は、投稿(Post)がリソースになりますので、Post を CRUD操作するためのコントローラを作ろうと思います。

Laravelが用意している機能に乗っかる(使う)と、一から自分で考えてこれらの操作を実装するより、だいぶ楽に実装できますよ。

7.4. 投稿コントローラの作成

では、実際にコントローラを作ってきましょう。

artisan のコントローラ作成コマンドを一覧表示させる

まずはアプリケーションディレクトリに移動し、次のartisanコマンドを実行します。

するとコントローラ作成コマンドのオプションが表示されます。

-r あるいは –resource オプションを使えば、リソースコントローラを作ることができそうです。

コントローラを作成する

では、下のコマンドで投稿をコントロールする PostsController を作ってみましょう。

次のようにコマンドを打ちます

コントローラは複数のリソースを操作するため、 Postsのように複数形を名前に使う慣習があります。

また【–resource】オプションをつけると、コントローラ作成時に7つのメソッドが作成されます。

下のように、作成に成功しましたと表示が出たらOKです。

作成されたファイルの確認

このコマンドによって、下図のように、PostsController.php ファイルが作られます。

PostsControllerクラスには、あらかじめ、7つのメソッド(メンバー関数)が書かれています。

これは【–resource オプション】を付けて作成したためです。このオプションがなければ、メソッドが何もない空っぽのクラスができるところでした。

7つのメソッドは次のようになっています。

7つの基本メソッドの役割

上記PostsController にあるメソッドを下の表にまとめました。

アクション 用途
index 一覧表示(Read)
create 新規作成のためのフォーム表示(Create)
store 新規作成のためのデータ保存(Create)
show 1件の詳細表示(Read)
edit 既存レコードの変更のためのフォーム表示(Update)
update 既存レコードの変更のためのデータ保存(Update)
destroy 既存レコードの削除(Delete)

それぞれのメソッドでCRUDを実現していきます。

CRUDの4つの用途のために7つのアクションがある感じです。

CRUDの4つに対してアクションが7つと多いのは、次の理由のためです。

  • Readが、複数レコードの一覧表示と、1件だけの表示の2種類あること。
  • Create と Update がフォーム表示とデータ保存の2ステップ必要なこと

1つのアクションで済むのはDeleteだけ。ただし複数のレコードを一気に消したいなって思ったら、アクションをあとで追加したりできます。

なので基本は7つ、だけど後から追加する可能性もあると考えておいてください。

 

なお、公式マニュアルに7つの基本アクションをURIやルート名とセットに表示した表がありました。

こちらも役に立つので、載せておきますね。

7.5. 投稿一覧の表示機能作成

では、手始めとして、投稿一覧の表示画面を作ってみましょう。

Laravelのアプリケーションの構成の復習

まず、Laravelでのプログラミングのデザインパターンを復習します。

Laravelは他のフレームワークのように、MVCデザインパターンを使ってます。

MVCデザインパターンとは、

  • データベースとのやり取りの部分をモデル(Model)クラスとして作り
  • html に動的に変更するデータを組み込んでページを構成する部分をビュー(View)として作り
  • ブラウザからのアクセス要求に対して、モデルやビューを使いながら送信する返答を作成する処理をコントローラ(Controller)クラスの中に作る

というソフトウェアのデザインです。

モデル、ビュー、コントローラの頭文字をとってMVCデザインパターンと呼んでいます。

この3つに加えて、ブラウザからの要求を読み説いて、どのコントローラを呼び出すかを判断するルーター(Router)というのがあります。

分かりやすいように図にしてみました。

Laravelの構成とMVCデザインパターン

Laravelでは、コントローラ、モデル、ビュー、ルーター 部分に、プログラムコードを書いていくことになります。

ルート設定をする

まずルータの設定部分であるルート設定を行います。

ルート設定とは、リクエストURLに応じて処理の受け渡しを決定する仕組みのこと。

すべてお任せの場合は、一行で7つのアクションをすべて定義してくれる設定方法があります。

ルート設定ファイル routes/web.php ファイルに以下の1文の設定を追加してください。

これは posts という名称と、PostsController というコントローラを使って、リソースコントローラ用のルート設定を追加するという意味になります。

Route::get だとか、Route::post とかの設定で同じことを書くと7文必要になるのですが、上記のように書けば1行で済みます。

一行で書いたルート設定resource(‘posts’, ’PostsController’) の意味

上記のように書くと、実際にどのような処理の振り分けをしてくれるのか調べる artisan のコマンドが用意されています。

調べてみましょう。

コマンドを入力するターミナルソフトの横幅を大きくして、 php artisan route:list  とコマンド実行してみましょう。

すると、以下のようなルート設定が表示されます。

説明のために下に今回ルート設定に追加したPostsController関連だけ下図に抜粋します。

7個のルート設定がされています。

URIと書いてあるのが、アクセスするときのURLのディレクトリ部分です。

例えば、一番上は単に【posts】と書かれています。

のようにブラウザで /posts にアクセスすると、Actionに記述してある通り  PostsController コントローラ のindex メソッドを呼び出すという意味になっています。

それぞれのアクションの メソッドとURI の組み合わせを下の表に抜粋します。

メソッド と URI の組み合わせで、アクション を判断します。

アクション URI メソッド
index https://example.com/posts GET でアクセス
create https:/example.com/posts/create GET でアクセス
store https:/example.com/posts POST でアクセス
show https:/example.com/post/{投稿ID} GET でアクセス
edit https:/example.com/posts/{投稿ID}/edit GET でアクセス
update https:/example.com/posts/{投稿ID} PUT か PATCH でアクセス
destroy https:/example.com/posts/{投稿ID} DELETEでアクセス

メソッドの違いがあるので、URI部分は同じでもよく、結果としてシンプルなURIでアクセスすることができます。

補足:メソッドは大きく分けてGETとPOSTの2種類。ブラウザからのデータ送信方法が違う

Methodは次の通りです。

大きな分類のメソッド 対象メソッド データの送信方法
GET GET
HEAD
サーバからデータを受け取るために使用する。
ブラウザから情報をサーバに送りたいときは、クエリパラメータとしてURLに追加される。
例:以下のURLの ? の page=1&category_id=3 の部分。
https://example.com/products?page=1&category_id=3
POST POST
PUT
PATCH
DELETE
サーバにデータを送信するために使用する。また結果としてサーバからはGETメソッド同様にデータを受け取る。
GETとの違いは、データを送るとき、URLに書かず、送信データの一部として送ること。
このため、文字以外の画像とかバイナリデータも送ることができる。
また、送信データがURLに表示されないため、パスワードなど人の目に触れさせたくないデータを送るのに向いている。

ブラウザで通常URL を指定してアクセスするときは、GET メソッドを使っています。

そのほかに、フォーム を使ってブラウザからサーバーにデータを送るとき、POSTメソッドを使ったりします。

ここでは、そのほかに、PUT あるいは PATCH メソッド、DELETE メソッドが出てきています。GET あるいは HEAD 以外は フォームからアクセスするときの方式と覚えておいてください。

大きく分けると、ブラウザからサーバにデータを URLについでに書いて送る方式をGETメソッド、そうではなく送信データとして送るのがPOSTメソッドと覚えておくとよいでしょう。

そして、PUT、PATCH、DELETEメソッドというのはPOSTメソッドと同じ仕組みを使っていて、サーバー側で処理を切り分けるためだけに使っています。

コントローラを実装する

ルート設定の後は、コントローラを実装します。

今回は一覧表示を追加するので、PostsController コントローラの index メソッドを修正します。

app/Http/Controllers/PostsController.php ファイルの6行目あたりに下記を追加してください。

ここから書く【Post】は、Appフォルダの下にある【Post】のことだよ、という意味になります。

次に次の2行を最初のメソッドに追加してください。

追加後は下図のようになります。

短いですが、まさに、コントローラから、モデルとビューを操作して、ブラウザに返信するhtmlのデータを作成しています。

それぞれのコードを説明します。

で、Postモデルを使って、データベースに保存されているすべての投稿を読みだして、$posts変数に代入しています。

そして、

では、ビューの posts/index.blade.php  ファイルに、今作った $posts 変数で すべての投稿のデータを渡して、htmlのページを作成しています。

return とあるので、作成したデータを このメソッドを呼び出した人に返答して処理を終了しています。その人(人じゃないですが^^;)は、そのまま、ブラウザ(閲覧者)にhtmlのページを送ってるんですね。

今回は、Post::all() のstaticメソッドを呼び出すために、Post モデルに処理を追加する必要はありません。もともとPostモデルの継承元のクラスに備わっているためです。

ビューを実装する

最後にビューを作ります。

ビューは、基本的には php ファイルなのですが、html寄りのphpファイルになります。

つまり、htmlファイルの一部に <?php ?> タグで PHPコードを埋め込むような感じのファイルです。

ただし違いがあり、<?php ?> でPHPコードを埋め込むより、楽にデータを埋め込めるように省略表記ができるようになっています。この機能をテンプレート機能といいます。

Laravelにはblade というテンプレート処理エンジンが組み込まれています。なので、ビューのファイルの拡張子は、blade.php となっています。

コントローラから呼び出すときは、【blade.php】の部分を省略して書きます。

今回、コントローラからは、

と書きました。これは、posts/index.blade.php ファイルを呼び出すという意味です。

ですので、posts フォルダとその中の index.blade.php というファイルを作成していきましょう。

ファイルの位置

ビューのフォルダやファイルは、resources/views フォルダの下に作ります。

views フォルダの下に postsフォルダを作り、その中にindex.blade.php ファイルを作りましょう。

そしてindex.blade.phpに以下のプログラムコードを入力してください。

ファイルの中身は以下のようになります。

@記号で始まる行が、bladeテンプレートエンジンの機能になります。

これにより<?php ?>タグがなくても、変数を組み込んだり、繰り返し表示させたりと、動的なページを作成することができます。

ざっと内容を説明すると、投稿をひとつづつ、タイトルと投稿者、作成日を表示していきます。レイアウトとしては、ブートストラップにあるcss を利用しています。cardとかrowの部分ですね。

そして、タイトルをクリックしたら、詳細ページに飛ぶようにリンクを設定しています。

以下、htmlの説明は省いて、bladeテンプレートエンジンの命令について説明していきます。

bladeテンプレートエンジンの命令の説明

共通部分の指定

これは、共通部分として views/layouts/app.blade.php ファイルを使用するという意味です。

共通部分のファイルをレイアウトファイルという言い方をします。主に、htmlのヘッダ部分だとか、ページのヘッダ、フッタ部分などを共通部分として記述してます。

今回、ログイン機能を組み込んだ時に一緒にLaravelによって組み込まれた表示をそのまま使ってます。

ページ固有部分の実装

レイアウトファイルには、ページごとに違う処理を書きたい部分を指定しておくことができます。

例えば、layouts/app.blade.php には、以下の記述があります。

これは、content というセクションの内容を埋め込んで表示するという意味になります。

さて、そして、posts/index.blade.php には @section 命令があります。

この命令は、@endsection までの記述を ベースとなるlayouts/app.blade.phpの @yield(‘content’) の位置に埋め込んでねという命令です。

セクションの終了位置を意味します。

foreachによる繰り返し処理

これはphp のforeach と同じ意味です。コンパクトに書けるというメリットがり、また終了タグもわかりやすいというメリットがあります。

コントローラから渡された ‘posts’ という名前のデータは $posts という変数で使用できます。今回 foreach の中で、投稿1つ1つを$post という名前で参照することができます。

はforeachの終了位置を示します。このタグまでの記述が繰り返されます。

PHPコードの埋め込み

上の1行のコードのうち、bladeテンプレート機能は、 {{ }} の「ダブル波かっこ」になります。これは中のPHPの実行結果を表示するという意味になります。その際、htmlタグはエスケープ処理されるところが特徴です。

同じことをPHPコードで書こうとすると、

という長いコードになってしまいます。

 

ちなみにhtmlタグをエスケープ処理せずに表示する場合は、通常のphpコードでは次のように書きます。

bladeテンプレートでは、{!! !!} で記述を囲みます。これは、次回以降で使うので、またその時に説明しますね。

 

説明を続けると、 {{ }}の中の route() 関数は、blade.phpの機能ではないのですが、laravel の関数になります。つまり、route()関数はビューの中だけでなく、コントローラでも使えるということを意味します。

route()は、URL を /posts/edit などのように実際のURLで指定するのではなく、ルート設定で設定したときのルート名で指定できるというものです。

例えば、投稿の詳細表示は、下のルート設定情報の赤枠でした。今回、これを呼びたいのですが、Name のカラムに posts.show と記述があります。

route()関数は、このルート設定につけられた名前を使って、URI posts/投稿IDを自動で作ってくれます。なかなか便利な機能です。

ですが、もしかして、「普通に

と書いたほうが楽じゃないか」とか思いませんでしたか?

確かに、こう書いてある解説書も多いですし、記述も楽ですよね。

でも、まずい場合があるんです。

例えばアプリを配置した ルートURLが、

のように http://ドメイン名/ 直下じゃないときを考えてください。

この時、

としてしまうと、

に飛んでほしいのに、

に飛んでしまいます。

route() 関数を使えば、ちゃんとアプリのトップURLからのURLを作成してくれます。

なのでroute()を使う癖をつけておくことをおすすめします。route を使わないときは、トップURLにディレクトリが含まれないことを確認するようにしてください。

Postモデルに変更が必要な参照

さて、ひとつだけ注意点があります。

bladeファイルには、 下記のようにPHPコードを埋め込みました。

このうち、 $post->user->nameの部分は、投稿ユーザ名を表示している部分なのですが、Postモデルには、user_id はあっても ユーザやユーザ名はないので、このまま実行するとエラーになります。

そうならないために、実行前に、Post モデルに変更を加える必要があります。

変更の仕方を解説します。

モデルの実装

今回、ビューから 投稿ユーザ名を参照するために、モデルに以下のメソッドを追加します。

モデルは、app/Post.php のファイルです。

追加後のPostモデルのコードは以下のようになります。

これはリレーションを設定しています。

データベースのSQL言語では、例えば 今回のposts テーブルからデータを読み出すときに、user_id を使って、対応する user テーブルも一緒に読み出すことができます。

そうすることで、user テーブルに定義されている name の情報も一緒に参照することができるんです。

同じことをlaravelでやるときは、リレーションを設定します。

リレーションは関係という意味ですね。

公式マニュアルには以下のようにリレーションの説明があります。

つまり、Post には user_id というカラムがあって、user_id と同じid をもつUser モデルと関連付けるためには、belongsTo()メソッドを使って定義するということになります。

id名がuser_id とわかりやすい名前になっているため、user_id を使うように明確に指示しなくても、belongsTo(‘App\User’); の User という名前から user_id を自動的に使ってくれます。

もし違う名前にしている場合には、belongsTo()メソッドに第二引数として、カラム名を指示してください。

例えば、user_id とせずに、author_id などと Post に定義してしまった場合、

のように指定してください。

メニューにブログ記事一覧へのリンクをはろう

最後に、下図のように、今回作った投稿一覧表示へのリンクを作りましょう。

先ほど、説明しましたが、メニューは共通部分になるので、

resources/views/layouts/app.blade.php ファイルに該当箇所があります。

「Right Side Of Navbar」 という【ナビゲーションバーの右側】を意味するコメント文を頼りに、以下のように3行のメニューを足してください。

 

route()関数を使って、URLを指定しています。

以上で変更箇所は終了です。

表示テスト

それでは、テストしてみましょう。

artisanのコマンドでサーバを起動して接続する場合には、下記のようにコマンドを打ちます。

URLは「http://127.0.0.1:8000/」となります。

Laravelホーム画面

まずは、もしまだユーザを一人も登録してない場合、サーバーに接続してLaravel画面を表示して、右上の「Register」からユーザーを一人登録しておいてください。

これは前回の演習で Postのテストデータにuser_id = 1 と入力しているからです。user_id に対応するユーザがいないってなるとまずいので登録必要ということです。

 

登録後、「http://127.0.0.1:8000/posts」に移動します。あるいはメニューの「ブログ」をクリックしてください。

下図のようにPostのテストデータが表示されればOKです。

表示されましたでしょうか?

タイトルをクリックしても、まだ、投稿の詳細表示画面を実装していないため、白い画面が表示されるだけです。次回、詳細表示画面を実装していきましょう。

エラーが発生してしまったら

少しずつですがいろんなファイルを変更しているので、うまくいかない場合もあるかもしれません。

ひとつづつ、正しく入力できているか、チェックしてみてください。

文章を書くときって、一回でうまく行くことはそれほど多くないと思います。プログラミングでも、一発で動くことはまれで、大体どこかタイプミスしてたりするものです。

僕も、記事もプログラムコードも修正しまくりです。

でも、そういうものだと思っています。

それでもプログラマになれるので、安心してください^^;

 

なお、この記事では、laravel7.25 と、XAMPP7.4.8(PHP 7.4.8、MariaDB 10.4.13、Apache2.4.43) を使ってテストしています。あと、Xserverでは、X10でPHP 7.3.16 でデプロイ後動作確認してます。

まとめ

blog記事の投稿一覧表示機能を実装しながら、以下のことを学びました

  • CRUD操作について
  • artisanのリソースコントローラ作成コマンド
  • リソースことローラの7つのアクション
  • LaravelのMVCデザインパターン
  • resourceを使ったルート設定
  • GET、POSTとその他メソッドについて
  • コントローラの実装
  • ビューの実装とbladeテンプレートエンジンの概略
  • モデルの実装とリレーション設定のうち belongsTo

今回はいろんな機能を説明しましたので、てんこ盛りになってしまいました。

よかったら何度か読み返したり、参考サイトを見たりしてください。

もし、見直してエラー内容がわからない場合、コメントかメッセージでお気軽にご質問ください。

過去に遭遇した問題など、わかる範囲でお答えします。

例えば、DBのバージョンが違うと、マイグレーションでエラーが発生する可能性もあります。

たしかstring型で191文字までしか作成できないため、string(‘title’)などとすると255文字で作成しようとしてエラーが発生したことがあった気がします。string(‘title’, 191)のようにすれば回避できるはずです。

それでは、また次回も作成を続けていきましょう。

 

===目次===

  1. laravelはPHPで動くフレームワーク ~laravel入門01~
  2. laravelでログイン機能付きサイトを作ってみよう、作成予定のWebアプリケーションの概要と作業手順の概略~laravel入門~
  3. 開発環境のインストール
    1. XAMPP
    2. VS code
    3. Git for Windows
    4. SourceTree
  4. laravelインストール
    1. composerインストール
    2. laravel本体インストール
    3. laravelのUIインストール
    4. node.jsインストール
  5. アプリ作成
    1. データベース設定
    2. ログイン機能追加
      1. npmインストール
      2.  css, jsコンパイル
    3. Topページ作成
    4. Aboutページ作成
    5. 問い合わせページ作成
      1. 問い合わせページからメール送信 ~Laravel7入門~
    6. Blog機能作成
      1. Model作成と一緒にmigrationファイルも作る。~Laravel7入門~
      2. リソース コントローラを自動生成して CRUD のうち一覧表示 indexアクションを実装する ~Laravel7入門~
      3. リソース コントローラで、詳細表示 showアクション を実装する ~Laravel7入門~
      4. リソースコントローラで新規作成:create, storeアクション を実装する~Laravel7入門~
      5. bladeテンプレートエンジンでタグを無視させつつ、改行を表示させる方法 ~Laravel7入門~
      6. リソースコントローラで更新:edit, updateアクション を実装する~Laravel7入門~
      7. リソースコントローラで削除:destroyアクション を実装する~Laravel7入門~
      8. 投稿にカバー画像を追加する ~Laravel7入門~

 

この記事が気に入ったら
いいね ! しよう

コメント