Challenge 3: Convert Manual Lookup to Route Model Binding — Possible Solution ==================================================================== // BEFORE — manual lookup use App\Models\Book; public function show(string $id) { $book = Book::findOrFail($id); return view('books.show', ['book' => $book]); } // AFTER — route model binding use App\Models\Book; public function show(Book $book) { return view('books.show', ['book' => $book]); } // routes/web.php — the route parameter name must match the variable name Route::get('/books/{book}', [BookController::class, 'show'])->name('books.show'); WHAT HAPPENS DIFFERENTLY IF THE ID DOESN'T EXIST ----------------------------------------------------- In BOTH versions, a nonexistent ID actually results in the exact same outcome: Laravel automatically throws a Illuminate\Database\Eloquent\ModelNotFoundException, which Laravel's default exception handling converts into a 404 Not Found response shown to the visitor. The difference is entirely about WHERE that behavior comes from: - In the "before" version, Book::findOrFail($id) is an explicit method call the developer wrote — findOrFail() is what throws ModelNotFoundException if no row matches; this is visible, deliberate code sitting right there in the method body. - In the "after" version, there is no findOrFail() call anywhere in the method at all — Laravel's route model binding does the equivalent lookup automatically, BEFORE the show() method's body ever executes, and throws the same exception on the framework's own initiative if the {book} route segment doesn't correspond to a real Product row. Practically, this means: if a developer ever needed different behavior for a missing book (returning a specific fallback book, logging something custom, redirecting instead of 404ing), route model binding's automatic behavior would need to be explicitly overridden (e.g. via a custom resolveRouteBinding() method on the model, or falling back to a manual $id parameter and calling Book::find($id) instead of Book::findOrFail()) — whereas with the manual version, that customization is just a normal code change to the existing findOrFail() call. WHY THIS WORKS -------------- - Route model binding matches the {book} segment in the route definition to the $book parameter in the controller method BY NAME — this is why the route parameter must be named {book} (not {id} or anything else) for this specific binding to work automatically. - The type hint `Book $book` (rather than `string $book`) is what tells Laravel which Eloquent model to query — Laravel infers the primary key column to look up (id, by default) from the model class itself.