Laravel controller method with model as parameter

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company

Mastering Eloquent: Using Models as Parameters in Laravel Controllers

As a senior developer, we often encounter scenarios where understanding how frameworks handle data flow—especially between routes, controllers, and models—is crucial for writing clean, scalable, and maintainable code. The observation you made regarding your controller methods (show(Transaction $transaction), edit(Transaction $transaction)) is pointing directly toward one of Laravel’s most elegant features: Route Model Binding.

This post will demystify how this mechanism works, why it simplifies your code, and exactly how you integrate it into your web routing. We will move beyond just seeing the syntax to understanding the underlying principles that make Laravel development so powerful.

Understanding Route Model Binding

When Laravel sees type-hinted parameters in a controller method (like $transaction of type Transaction), it automatically attempts to resolve an Eloquent model instance from the route definition based on the provided identifier (usually the route parameter). This process is known as Route Model Binding.

Instead of manually fetching the data inside your controller using findOrFail($id), Laravel handles the entire retrieval and instantiation for you, reducing boilerplate code significantly. This adheres to the principle of separation of concerns—the route defines what resource we are dealing with, and the controller focuses solely on how to handle that resource.

Implementing Route Model Binding

To make this work, you need three components: a Model, a Route definition, and the Controller method itself.

Step 1: Ensure Your Setup is Correct

Assuming you have already run php artisan make:model Transaction -a, you now have the necessary Eloquent model ready to go.

Step 2: Define the Route with Binding

In your routes/web.php file, instead of passing a simple string or integer to the controller, you use the Model class name directly as the parameter. Laravel's router is smart enough to map this request to an Eloquent query.

For instance, if you want to fetch a specific transaction by its ID:

// routes/web.php

use App\Http\Controllers\TransactionController;
use Illuminate\Support\Facades\Route;

Route::get('/transactions/{transaction}', [TransactionController::class, 'show']);
Route::get('/transactions/{transaction}/edit', [TransactionController::class, 'edit']);

Notice how we use {transaction} in the URL. Laravel automatically maps this parameter to the transaction argument expected by your controller method. When a request hits /transactions/5, Laravel automatically queries the database for the transaction where the primary key is 5 and injects that resulting Transaction model object directly into the show method.

Step 3: The Controller Implementation

With the route set up correctly, your controller methods become clean and focus purely on business logic, as they already receive the fully hydrated model instance.

// app/Http/Controllers/TransactionController.php

namespace App\Http\Controllers;

use App\Models\Transaction; // Ensure you import your model
use Illuminate\Http\Request;

class TransactionController extends Controller
{
    /**
     * Display the specified resource.
     * Laravel automatically injects the Transaction model based on the route.
     *
     * @param  \App\Models\Transaction  $transaction
     * @return \Illuminate\Http\Response
     */
    public function show(Transaction $transaction)
    {
        // The $transaction variable is already an Eloquent model instance!
        return view('transactions.show', ['transaction' => $transaction]);
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\Models\Transaction  $transaction
     * @return \Illuminate\Http\Response
     */
    public function edit(Transaction $transaction)
    {
        // You can now access model attributes directly:
        // $data = $transaction->toArray();

        return view('transactions.edit', ['transaction' => $transaction]);
    }
}

Why This Approach is Best Practice

Using Route Model Binding offers significant advantages over manually fetching data in the controller:

  1. Reduced Boilerplate: You eliminate repetitive code like Transaction::findOrFail($id). The framework handles the database interaction for you.
  2. Improved Readability: The controller methods clearly declare what they expect, making the intent of the code immediately obvious. This is a core tenet of writing clean PHP within the Laravel ecosystem.
  3. Centralized Logic: It keeps the data retrieval logic closer to the routing layer where it belongs, promoting better separation of concerns. As you explore more complex relationships and services, adhering to these patterns will make your application structure much more robust, aligning with the philosophy behind frameworks like Laravel.

Conclusion

The concept demonstrated here—using Eloquent Models directly as parameters in controller methods via Route Model Binding—is a hallmark of effective Laravel development. By leveraging this feature, you move away from manual data fetching and embrace a more declarative way of defining your application's flow. Always strive to use the tools provided by the framework; they are designed to make complex tasks simple and elegant.