■P079
────────────────
sail artisan make:controller Tweet/Update/IndexController --invokable
────────────────

────────────────
sail artisan make:controller Tweet/Update/PutController --invokable
────────────────

────────────────
sail artisan make:request Tweet/UpdateRequest
────────────────


■P080

●app/Http/Requests/Tweet/UpdateRequest.php
────────────────
<?php

namespace App\Http\Requests\Tweet;

use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Foundation\Http\FormRequest;

class UpdateRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     */
    public function authorize(): bool
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, ValidationRule|array<mixed>|string>
     */
    public function rules(): array
    {
        return [
            'tweet' => 'required|max:140',
        ];
    }
    
    public function tweet(): string
        {
            return $this->input('tweet');
        }
}
────────────────


■P081

●routes/web.php
────────────────
Route::get('/tweet/update/{tweetId}', \App\Http\Controllers\Tweet\Update\IndexController::class)->name('tweet.update.index');
Route::put('/tweet/update/{tweetId}', \App\Http\Controllers\Tweet\Update\PutController::class)->name('tweet.update.put');
────────────────

────────────────
Route::get('/tweet/update/{tweetId}', \App\Http\Controllers\Tweet\Update\IndexController::class)->name('tweet.update.index')->where('tweetId', '[0-9]+');
Route::put('/tweet/update/{tweetId}', \App\Http\Controllers\Tweet\Update\PutController::class)->name('tweet.update.put')->where('tweetId', '[0-9]+');
────────────────

────────────────
sail artisan make:provider RouteServiceProvider
────────────────


■P082

●app/Providers/RouteServiceProvider.php
────────────────
<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class RouteServiceProvider extends ServiceProvider
{
    /**
     * Register services.
     */
    public function register(): void
    {
        //
    }

    /**
     * Bootstrap services.
     */
    public function boot(): void
    {
        //
    }
}
────────────────


■P083

●app/Providers/RouteServiceProvider.php
────────────────
use Illuminate\Support\Facades\Route;
use Illuminate\Support\ServiceProvider;

// 略

public function boot()
{
    Route::pattern('tweetId', '[0-9]+');
		// 略
}
────────────────

────────────────
Route::get('/tweet/{tweetId}', \App\Http\Controllers\Tweet\Update\IndexController::class)->name('tweet.update.index');
Route::put('/tweet/{tweetId}', \App\Http\Controllers\Tweet\Update\PutController::class)->name('tweet.update.put');
────────────────

●app/Http/Controllers/Tweet/Update/IndexController.php
────────────────
    public function __invoke(Request $request)
    {
        $tweetId = (int) $request->route('tweetId');
        dd($tweetId);
    }
────────────────


■P084

●app/Http/Controllers/Tweet/Update/IndexController.php（全文）
────────────────
<?php

namespace App\Http\Controllers\Tweet\Update;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Tweet;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

class IndexController extends Controller
{
    /**
     * Handle the incoming request.
     */
    public function __invoke(Request $request)
    {
        $tweetId = (int) $request->route('tweetId');
        $tweet = Tweet::query()->where('id', $tweetId)->first();
        if (is_null($tweet)) {
            throw new NotFoundHttpException('存在しないツイートです');
        }
        dd($tweet);
    }
}
────────────────


●app/Http/Controllers/Tweet/Update/IndexController.php
────────────────
        $tweetId = (int) $request->route('tweetId');
        $tweet = Tweet::query()->where('id', $tweetId)->firstOrFail();
────────────────


■P085

●resources/views/tweet/update.blade.php
────────────────
<!doctype html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <title>つぶやきアプリ</title>
</head>
<body>
<h1>つぶやきを編集する</h1>
<div>
    <a href="{{ route('tweet.index') }}">< 戻る</a>
    <p>投稿フォーム</p>
    <form action="{{ route('tweet.update.put', ['tweetId' => $tweet->id]) }}" method="post">
        @method('PUT')
        @csrf
        <label for="tweet-content">つぶやき</label>
        <span>140文字まで</span>
        <textarea id="tweet-content" type="text" name="tweet" placeholder="つぶやきを入力">{{ $tweet->content }}</textarea>
        @error('tweet')
        <p style="color: red;">{{ $message }}</p>
        @enderror
        <button type="submit">編集</button>
    </form>
</div>
</body>
</html>
────────────────


■P086

●app/Http/Controllers/Tweet/Update/IndexController.php
────────────────
    public function __invoke(Request $request)
    {
        $tweetId = (int) $request->route('tweetId');
        $tweet = Tweet::query()->where('id', $tweetId)->firstOrFail();
        return view('tweet.update')->with('tweet', $tweet);
    }
────────────────


■P088

●app/Http/Requests/Tweet/UpdateRequest.php
────────────────
    public function id(): int
    {
        return (int) $this->route('tweetId');
    }
}
────────────────


●app/Http/Controllers/Tweet/Update/PutController.php（全文）
────────────────
<?php

namespace App\Http\Controllers\Tweet\Update;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Http\Requests\Tweet\UpdateRequest;
use App\Models\Tweet;

class PutController extends Controller
{
    /**
     * Handle the incoming request.
     */
    public function __invoke(UpdateRequest $request)
    {
        $tweet = Tweet::query()->where('id', $request->id())->firstOrFail();
        $tweet->content = $request->tweet();
        $tweet->save();
        return redirect()
            ->route('tweet.update.index', ['tweetId' => $tweet->id])
            ->with('feedback.success', "つぶやきを編集しました");
    }
}
────────────────


■P089

●resources/views/tweet/update.blade.php
────────────────
    <a href="{{ route('tweet.index') }}">< 戻る</a>
    <p>投稿フォーム</p>
    @if (session('feedback.success'))
        <p style="color: green">{{ session('feedback.success') }}</p>
    @endif
────────────────


■P090

●resources/views/tweet/index.blade.php
────────────────
        @foreach($tweets as $tweet)
            <details>
                <summary>{{ $tweet->content }}</summary>
                <div>
                    <a href="{{ route('tweet.update.index', ['tweetId' => $tweet->id]) }}">編集</a>
                </div>
            </details>
        @endforeach
────────────────
