Laravelには、通常のコントローラー以外にも、リソースコントローラー(resource controller)という便利コントローラーがあります。
何が便利かというと、リソースコントローラーを使うと、新規投稿、編集、削除、表示といった、ブログや投稿サイトでは必ず必要になってくる一連のCRUD操作をセットで作れるようになる事です。
Resource ControllerのCRUDって何よ?
CRUD(クラッド)とかいうなんかファンタジーアニメに出てきそうなカッコいい謎用語がいきなり出てきやがりましたが、
Create(新規作成)、Read(読み出し)、Update(更新)、Delete(削除)
の頭文字を取ったものです。
仮にブログなら、投稿を新規作成し、その投稿を読み出して表示し、その後、編集&更新し、時には削除しますよね。
その4機能をまとめてCRUDって呼んでるんです。
CRUDを全部まとめてやってくれるResource Controller
この4機能、通常のコントローラーで自作すると、結構管理が面倒です。Route(web.php)にも、get, post,get, post...って沢山書いて、沢山指示を書かなきゃいけません。
でも、Resource Controllerなら、それが不要になり、この4動作を1つのコントローラーで自動管理してくれるようになります。
Resource Controllerの作り方
とにかく1度、Resource Controllerを自分で作ってみましょう。作れば何が便利なのか理解できます。
コマンドプロンプト(Shell/ターミナル)を開いて、
php artisan make:controller SampleController --resource
と入力、Enterします。--resourceと最後に付ける事で、リソースコントローラーは作成できます。
Sampleの部分はもちろん自由に変えてください。
そして、app\http\Controllersフォルダに行き、今作ったコントローラーを実際に開いてみてください。以下のように7メソッド(function)が並んでるはずです。(コメントアウト部分はいらないので削除してあります。)
Resource Controllerの7メソッドの意味、使い方
それぞれのメソッド(public function)の使い方ですが、
index: サイトのTOPページ、投稿一覧などを表示するためのメソッドを書く。
create: 新規投稿作成ページを表示するためのメソッドを書く。
store: 新規投稿をデータベースに保存するためのメソッドを書く。
show: 投稿の個別ページを表示するためのメソッドを書く。
edit: 投稿の編集ページを表示するメソッドを書く
update: 編集した投稿をデータベースに上書き保存するメソッドを書く
destroy: 投稿を削除するメソッドを書く。
といった具合に、ブログや投稿サイトの一連の作業に必要な7動作を1つのコントローラーで一元管理するのが、Resource Controllerです。
実際のResource Controllerの書き方例
一応それぞれのメソッドの書き方例を出しておきます。
コピーしました
コピー
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Post;
class SampleController extends Controller
{
// ログイン認証をedit,update,destroyにだけかける
public function __construct()
{
$this->middleware('auth', ['only' => ['edit', 'update', 'destroy']]);
}
// TOPページの表示
public function index()
{
// 1ページに10件新着順で表示
$val = Post::orderby('created_at', 'DESC')->paginate(10);
return view ('sample.index')->with('val', $val);
}
// 新規投稿作成ページの表示
public function create()
{
return view ('sample.create');
}
// 作成した投稿を保存
public function store(Request $request)
{
$post = new Post;
$post->user_id = auth()->id();
$post->title = $request->title;
$post->main = $request->main;
$post->save();
return redirect('/sample');
}
// 投稿の個別ページ表示
public function show($id)
{
// URLのidと一致する投稿を取得
$val = Post::findOrFail($id);
return view ('sample.show')->with('val', $val);
}
// 投稿編集ページを表示
public function edit($id)
{
// URLと一致する投稿を取得
$val = Post::findOrFail($id);
// ログインユーザーとuser_idが一致しない場合はTOPにリダイレクトする
if($val->user_id == auth()->id()){
return view('sample.edit')->with('val',$val);
}else{
return redirect('/sample');
}
}
// 編集した投稿を上書き保存
public function update(Request $request, $id)
{
// 同じIDの投稿を探して、上書き保存
$post = Post::findOrFail($id);
$post->title = $request->title;
$post->main = $request->main;
$post->save();
return redirect('/sample');
}
// 投稿を削除
public function destroy($id)
{
// URLと一致する投稿が見つかれば、削除。
$post = Ask::findOrFail($id)->delete();
return redirect('/sample');
}
}
基本的に、投稿の編集ができるのは、ログインユーザー(投稿した本人)だけにしますよね。なのでeditやupdate, destroyにだけは、ログインしてないユーザーのアクセスを禁止するようにmiddleware AUTHを冒頭で設定してます。
→Laravelのミドルウェアとは?初心者にもよく分かる図で解説!
→Laravelで特定ページへ飛ぶ前にログイン表示3方法+ハッキング対策
Request $requestがなんなのか分かってない場合は
→LaravelのControllerのRequestとは?初心者でも図解と例でバッチリ分かる!
その他、コントローラーの記述について
→Laravelのuseとは?超初心者向けにシンプルに分かりやすく解説
→laravelでpagination(ページ送り)の作り方。初心者もよく分かる図解。
→入門!laravelでデータベースから取得。クエリの書き方(エロクワント版)
→Laravelのfind()とfindOrFail()の違い、使い分け方。初心者もよく分かる!
さて、コントローラーの設定を書いたら、今度はルートとブレードも設定していきましょう。
Resource Controllerは、web.phpでRoute::resourceを使う。
次に、routes\web.phpを開いてください。
通常のコントローラーなら、Route::getかRoute::postを使って、ページを表示したり、投稿を送信したりしますよね。
→Laravelのroutes(web.php)とは?超初心者向けに図解と実例でやさしく解説!
でも、リソースコントローラーの場合は、Route::resourceと書きます。()内のアドレス部分は、'/sample'のように、TOPページ用アドレス(indexメソッド用)を書きます。そして、最後にコントローラー名だけ書きます。
これだけ書けば、あとはpostやgetなどの判別はリソースコントローラー側で自動でやってくれるんです。本来なら、7行のget, postを書く所が、たった1行で全部やってくれるんです。web.phpの表記がすごくスッキリしますね。
Resource Controllerでバグを防止するための、Routesへの追記
ちなみに、Resource Controllerには、7つのメソッド(public funciton)が自動生成されますが、場合によっては、「削除機能はいらない」とか「編集できないようにするから、編集画面作らない」など、使わない機能もあるはずです。
その場合は、web.phpにこう書きます。
コピーしました
コピー
['only' => ['index', 'show', 'edit', 'update']]
のように、onlyと書いて、使うメソッド名だけ書きます。そうする事で、未使用のメソッドは動かなくなるので、バグやエラーが出る事を防ぐ事ができます。
Resource Controllerの7メソッドのURLの調べ方
コマンドプロンプトに、
php artisan route:list
と打ってください。
で、ズズーっと画面を広げてみてください。
こういうテーブルが表示されます。そこに、今回作ったSampleControllerのメソッド一覧が出てます。
例えば、個別投稿を表示するページ(show)なら、sample/{sample}と書いてありますが、{sample}の部分には、投稿IDが自動で入ります。つまり、https://abc.com/sample/52 のように、データベースの投稿IDがページURLになります。
投稿の編集ページなら、/sample/52/edit のようなアドレスになるという事です。
投稿の新規作成ページなら、/sample/create がURLです。
このように、URLが自動生成されます。
ブレードに投稿フォームを作って送信する場合の送信先URLは?
では、仮に下のような新規投稿フォームをブレードに作った場合、どこに送信すればいいんでしょうか?
route::listを見ると、
sample.storeは、sampleがURLですから、
<form action="/sample" method="post">のように、actionにURLを指定します。
ちなみに、画像のenctype="multipart/form-data"は画像などのファイルを送信する場合に必要なタグです。
そして、今度は、投稿の編集画面を同じように作った場合、送信先は、
sample/{sample}なので、
<form action="/sample/{{$val->id}}" method="post">のような書き方になりまず。(editメソッドから$valで投稿idも受け取ってるので、$val->id を使う事で、投稿IDが代入される)
さらに、コマンド画面に、PUT|PATCHと書かれている通り、普通のPOSTだとエラーで上書きしてくれないので、
@method('PUT')と追記する必要があります。
こうする事で、投稿を更新保存してくれます。
Routeでnameを使う場合は?
普通のコントローラーだと、nameを指定する事がありますが、Resource Contorollerの場合は、nameはroute listのNameカラムに表示されているもの(sample.editなど)を使えばOKです。
Resource Controller用のBladeの作り方
Resource Controller用のBladeの作り方ですが、
まずresources\viewsフォルダに、sampleフォルダを作ります。
もしあなたの作ったコントローラーの名前が、PostControllerなら、postというフォルダを作るって事です。
そして、その中に、
create.blade.php(新規投稿作成ページ用)
edit.blade.php(投稿編集ページ用)
index.blade.php(topページ用)
show.blade.php(個別投稿表示ページ用)
の4つのブレードを作ってください。
これらで、それぞれのページを作成していきます。
もちろん、サイト全体のレイアウトは、別途layout.blade.phpなどを用意して書いて、継承して、コンテンツ部分だけを書けばOKだよ。
ブレード側で投稿フォームをどう作ってどう表示するかは↓
Laravel6チュートリアル初心者向け:フォームを作成し投稿を保存してみよう!
Laravel6チュートリアル初心者向け:データベースの値を取得して表示してみよう
というわけで、Resource Controllerを使うと、仕事が7倍楽になるので、どんどん使って行きましょう。