Laravel10:ViewからControllerにIDを渡す方法&エラー理由

経緯

Country/index.blade.php から、CountriesController/show($country_id) と 
id をViewからController に渡したかったです。
4hほど、下に書いてあるエラー達に苦しめられましたので、
ここに、解消したコードを共有します!
何かの一助になれば幸いです。
環境
エラー集
- App\Http\Controllers\CountriesController::show(): 
Argument #2 ($country_id) must be of type int, string given, 
called in /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Controller.php on line 5

- Too few arguments to function App\Http\Controllers\CountriesController::show(), 
1 passed in /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Controller.php on line 54 and exactly 2 expected

結論:Controllerから、ViewにModelを渡す時に、id を含め忘れていた。

本当に恥ずかしい原因だったのですが、Contry/index.blade.phpCountriesController / index()からCountryモデルを渡していたのですが
肝心の country_id を取得・渡し忘れていのが原因でした。。。
以下、コードになります。

### CountryController
<省略>
class CountriesController extends Controller
{
    public function index()
    {
        // NG例:$countries = Country::select('country_name')->paginate(5);
        $countries = Country::select('country_id', 'country_name')->paginate(5);
        return view("Country.index", compact('countries'));
    }

    public function show(int $country_id): View
    {
        $japanesePlayers = JapanesePlayer::all();
        return view("Players.Japan.index", compact('japanesePlayers'));
    }
}

上記のindex() / select()において、当初country_nameのみ取得していました。
そのため、dd($country_id) や、dump($country_id) で null が出続けていました。。。

### views/country/index.blade.php
<省略>
<tbody class="bg-white dark:bg-slate-800">
  foreach ($countries as $country)
    <tr>
      <td class="border-b border-slate-100 dark:border-slate-700 p-4 pl-8 text-slate-500 dark:text-slate-400">
        <a href="{{ route('countries.show', ['country_id' => $country->country_id]) }}">
          {{ $country->country_name }}
        <a>
      <td>
    <tr>
 @endforeach
<tbody>

### route/web.php
Route::get('/countries', [CountriesController::class, 'index']);
Route::get('/countries/{country_id}', [CountriesController::class, 'show'])->name('countries.show');

p.s. Controller の中で、ちょいちょい頭文字が大文字ですが、理由はHerokuにデプロイしているからです。

Laravel 10:諦めて Sail を使ってみたら、簡単だった。。。View [hoge.index] not found 解消

ポートフォリオ制作をしていて、そろそろ公開したく色々とやっていました。
そもそも、MAMP、Laravel 10 でアプリケーション開発をしていました。
Dockerは使っていません。
公開にあたり、Herokuを採用し、色々と試してみたものの上手くいかず
Dockerを採用することに、決めました。
ただ、エンジニア歴2年が経ったかなくらいの自分には、Dockerを使って環境構築するのが手間がかかりそうだったので、
そして、さらに4週間もかかっていたので、Sailが早そう!(たぶん)と思いSailを使ってDocker環境構築を採用することに決めました。。。

Redoubleサイトにある通りに、既存のアプリケーションに Sailを追加する流れになります。

$ composer require laravel/sail --dev
$ php artisan sail:install
┌ Which services would you like to install? ───────────────────┐
 │ mysql   <= を選択した

Docker Desktopを起動すること

$ ./vendor/bin/sail up -d

シェルエイリアスの設定

以下を実行すると、./vendor/bin/sailsailで実行できるようになる。

$ alias sail='sh $([ -f sail ] && echo sail || echo vendor/bin/sail)'

Laravel Breezeパッケージをインストールします。

$ sail composer require laravel/breeze --dev
$ sail php artisan breeze:install
$ sail npm install
$ sail npm run dev <= これで、Laravel の welcomeページが表示されます。sail artisan serveはダメでした。。。(理由がわからない。。。)

DB 設定

$ sail exec mysql bash               
bash-4.4# mysql -u root -p
Enter password: password(デフォルト)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| laravel            |
| mysql              |
| performance_schema |
| sys                |
| testing            |
+--------------------+

MySQLを使うなら、JawsDBにするべき!ClearDBは、古いからNG!

View [hoge.index] not found 解消!!!

  • 結論:HogeControllerの return view("hoge.index")return view("Hoge.index") する!
  • 理由:ローカルでは、大文字、小文字を識別しない(いいように解釈してくれる)が、Herokuはそこら辺が厳しいそう。
    • で、hoge.index の hoge は、フォルダ名を示していると思うが、フォルダ名と同じ名前にしないといけないそう。

参考サイト

SQLSTATE[HY000] [1045] Access denied for user '<DB_USERNAME>'@'localhost' (using password: YES)

度々、起こるDBへの接続拒否。アカウントのパスワードの不整合。

解消方法をまとめます。

環境

解決策

  • 「DB_SOCKET=」を「空」にしていたのが原因
    MAMP使っているなら、こちらの画面(画像)で確認できます。
    だいたい、同じはずで以下のパスを入力すればいいはず。
DB_SOCKET=/Applications/MAMP/tmp/mysql/mysql.sock

なんで、こんな単純なことでエラーになっていたかというと、
Herokuを使って、ポートフォリオを公開したくて、色々いじっていたのが原因です。
Herokuってmainブランチをデプロイするので、Heroku用に socketをいじっていて
ローカル開発時に戻し忘れてました。。。ちょっとめんどくさい。

因みに今は、Herokuを諦めて別のを模索中。without Docker でデプロイしたい!
最悪の最悪、Docker使いますが。。。というか最終的には Docker 使う予定ですが。一旦ね。

Laravel:indexページを開くまで(ルーティング)

前段

今までは、Udemyの教材を使ってLaravelを学習していました。
今度は、自分で勉強がてらCRUDを実装しようと思い、イチからプロジェクトを作成して...を始めました。
そして、最初につまずいたのが、indexページの表示。。。
なんとか表示まで辿り着いたので、振り返りを兼ねてまとめていきます!

プロジェクトの作成は、こちらを参考にしてください。(Laravel 10)

環境

大まかな流れ

  1. Http/Controllers/HelloController.phpを作成
  2. resources/views/index.blade.phpを作成
  3. routes/web.phpを追記

正直、3. のルートの書き方が一番のポイント!
それ以外は、テキトーなファイルを作成すればいいです。

1. Http/Controllers/HelloController.phpを作成

テキトーなコントローラを作成しましょう!
例えば、以下の感じ

<?php
namespace App\Http\Controllers;
use Illuminate\Routing\Controller as BaseController;

class HelloController extends BaseController
{
    public function index()
    {
        $data = [
            'msg' => 'Bladeテンプレートのサンプル',
        ];
        return view('index', $data);
    }
}

2. resources/views/index.blade.phpを作成

こちらもテキトーファイルを作成。
「ショートカットキー:shift + 1(= !)」で、簡単にHTMLテンプレを作成してくれます!

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Hello</title>
</head>
<body>
    <h1>とりあえず、indexページを開きたい</h1>
    <p>{{ $msg }}</p>
</body>
</html>

3. routes/web.phpを追記:ここがポイント!

  • 使いたいControllerをuse文で読み込む
  • Route()の第一引数は、好きなパスを指定。自由に決めれます。例、/hello
  • 第二引数のindexは、呼び出したいコントローラのメソッドを指定。例、index()
<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\HelloController;  ※これ追加

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider and all of them will
| be assigned to the "web" middleware group. Make something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});

Route::get('/hello', [HelloController::class, 'index']);  ※これ追加


以上、ここまでできたら、$ php artisan serveで起動して、
http://127.0.0.1:8000/helloすると indexページが開きます!



p.s. $ php artisan -Vを実行すると、自分のLaravelのversionを確認できますよ

MAMP:Apache couldn't be started. Please check your MAMP installation and configuration.

Laravelの学習として CRUD操作を実装しようと思い、MAMPを使おうとしていましたが、タイトルのエラーがでました。

環境

上記のエラーの解決した方法

  • Apacheが起動しているか確認するコマンド:% sudo lsof -i :80
  • Apacheの停止:% sudo apachectl stop
  • MAMP再起動
  • 無事、動いた!

Laravel 10 PUT:画像を特定のフォルダに格納する

【Laravel】マルチログイン機能を構築し本格的なECサイトをつくってみよう
↑ こちらの教材のメモになります。

  • InterventionImage を諦めて(リサイズだけだし...)、次に進むために画像をアップロードする必要がある。 書き方も変える必要がある。

  • メイントピック:Storage::putFileAs('public/shops/', $imageFile, $fileNameToStore);

    • putでやっていたら、永遠に画像名のフォルダが作られて、そこに画像が格納された。。。
    • 素直にputFileAs()を使うのがよかった。まあ、無事に解決できたし、次にいけるからいく!!
    public function update(Request $request, $id)
    {
        $imageFile = $request->image; //一時保存
        if(!is_null($imageFile) && $imageFile->isValid() ){
            // Storage:putFile('public/shops', $imageFile);
            $fileName = uniqid(rand().'_');
            $extension = $imageFile->extension();
            $fileNameToStore = $fileName. '.' . $extension;

            // dd($imageFile);

            Storage::putFileAs('public/shops/', $imageFile, $fileNameToStore);
        }
    }

参考

【PHP / Laravel】Storage の基本操作まとめ #PHP - Qiita

Laravel 10.x:compact関数

Udemyの教材:【Laravel】マルチログイン機能を構築し本格的なECサイトをつくってみよう【Breeze/tailwindcss】
こちらの学習のメモ書きとして、書いてます!

    public function edit($id)
    {
        $shop = Shop::findOrFail($id);
        return view('owner.shops.edit', compact('shop'));
    }

上記は、ShopController に記載されているものです。

Shopモデルから、引数にわたってくる $id と合致するデータを取得して、
変数 $shop に代入しています。

URL:owner/shops/edit/$id に画面が遷移します。

この際、compact()が、compact($shop)ではなく、compact('shop') になっているのがしっくりこなかったですが、
調べると、compact() は、連想配列を作っているそうです。
今回の例だと、['shop' => $shop] という連想配列になるそう。