1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

laravelの認識で間違っていたこと その1~Route-Controller間のパラメーター~

Posted at

#laravelのRoute-Controller間のパラメーター間違い
##言い訳
youtubeなんかの動画や初心者用のwebページなどをみてlaravelにおけるroute-controller間のパラメーターの受け渡しを学びました。(学んだつもりでした。)
まさか他の人が沼にハマるまいとは思いますが、救済する1本の蜘蛛の糸になれば幸いです。

##科学の力ってスゲー
フレームワークを利用し始めた当初簡単にsqliteのようなデータベースと接続し、簡単にSELECTできる(値を引っ張ってこれる)ことに感心していました。
「(データがあるテーブル名がpostsの場合)え?Post::find(1)だけでid=1の(レコードの)データをもって来れるの!?科学の力ってスゲー。」

###間違い
実際にハマっていた間違い↓

web.php
<?php

use Illuminate\Support\Facades\Route;

Route::get('/post','PostsController@index');
Route::post('/post/{id}','PostsController@detail');
//ルートの設定postで一覧画面、その後ろに数字をつけることで、そのidの詳細画面に行けるようにする 
PostController.php
namespace App\Http\Controllers;

use App\Post;
use Illuminate\Http\Request;

class PostsController extends Controller
{
    public function index()
    {
        $posts = Post::all();
        //postsテーブルの全データ取得

        return view('ichiran',['posts' => $posts]); 
        //表示は「ichiran.blade.php」の方に引数postsを渡して任せる
    }

    public function detail(Post $post)
    {
        $title = $post->title; 
        $body = $post->body; 
        //例えば/postページから/post/1へと遷移した時は$id=1のデータが勝手に取得される

        return view('shousai',['title' => $title,'body' => $body]); 
        //表示は「shousai.blade.php」の方に引数title,bodyを渡して任せる
        //普段は$postをビューの方に渡してそっちで{{ $post->title }}としていますよ、念為。
    }
}

/postページから/post/1へと遷移した時は$id=1のデータが勝手に取得されるなんて程、人生は甘くはないんですねぇ。
何万回試そうが、$id=1のデータは取れず…
###最初に見つけた解決策1

PostController.php
namespace App\Http\Controllers;

use App\Post;
use Illuminate\Http\Request;

class PostsController extends Controller
{
    //略

    public function detail(Post $post,$id)//<-new
    {
        $post = Post::find($id);
        //routeの方で{id}と指定したためcontrollerで使いたい時にはfunctionの引数に指定すれば使える
        //よって/post/1へと遷移したら$id=1のデータをfindすることができる

        $title = $post->title; 
        $body = $post->body; 

        return view('shousai',['title' => $title,'body' => $body]); 
    }
}

でもこれなんかスマート(ここで言うスマートとは「引数が多くなってるなぁ、function内の記述もちょっと多いし…なんかもっと削れないんかなぁ」程度のこと)でないなぁ…

###試行錯誤し、行きついた解決策2
まずrouteをちょっと変更し、{id}ではなく{post}にします。
そうすると…

web.php
<?php

use Illuminate\Support\Facades\Route;

Route::get('/post','PostsController@index');
Route::post('/post/{post}','PostsController@detail');
PostController.php
namespace App\Http\Controllers;

use App\Post;
use Illuminate\Http\Request;

class PostsController extends Controller
{
    //略

    public function detail(Post $post)//<-new
    {
        $title = $post->title; 
        $body = $post->body; 

        return view('shousai',['title' => $title,'body' => $body]); 
    }
}

これだけで$titleには{post}に渡された数字のデータが入るんですね。ビックリです。

いつも{id}で指定していたので、「なんでリソースコントローラー作るとeditには勝手に任意のデータが読み込まれるのだろう…リソースコントローラー専用なのか、ずるいな」と思っていました。

##からくり
detailファンクションの引数にPostモデルのインスタンスを指定してあげた(いわゆるDI)変数名とrouteで指定した変数名を合わせることで、URL内で指定した数値のデータをモデルから持ってくることができるんですね。

え?それの次が知りたい?
それはもっと偉い人に聞いてください。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?