Laravel10:ViewからControllerにIDを渡す方法&エラー理由
経緯
Country/index.blade.php から、CountriesController/show($country_id) と id をViewからController に渡したかったです。 4hほど、下に書いてあるエラー達に苦しめられましたので、 ここに、解消したコードを共有します! 何かの一助になれば幸いです。
環境
-
- M2チップ
- macOS:14.5
エラー集
- 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.phpにCountriesController / 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/sailをsailで実行できるようになる。
$ 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!
- 公式サイトより、ClearDBは
MySQL 5.5までだそう。 - ClearDBの欠点 - バージョンが古い
View [hoge.index] not found 解消!!!
- 結論:HogeControllerの
return view("hoge.index")をreturn view("Hoge.index")する! - 理由:ローカルでは、大文字、小文字を識別しない(いいように解釈してくれる)が、Herokuはそこら辺が厳しいそう。
参考サイト
SQLSTATE[HY000] [1045] Access denied for user '<DB_USERNAME>'@'localhost' (using password: YES)
度々、起こるDBへの接続拒否。アカウントのパスワードの不整合。
解消方法をまとめます。
環境
-
- M2チップ
- macOS:14.5
Laravel 10.X
解決策
- 「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)
環境
-
- M2チップ
- macOS:14.5
Laravel 10.X
大まかな流れ
Http/Controllers/HelloController.phpを作成resources/views/index.blade.phpを作成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を確認できますよ
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);
}
}
参考
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] という連想配列になるそう。