Laravel 5.4:如何通过中间件将模型对象传递给控制器​​?

时间:2017-07-30 07:33:00

标签: laravel laravel-5.4 laravel-middleware

我正在使用Laravel 5.4中的应用程序,我有一个中间件ValidateBooking,然后是一个控制器,其中url就像/booking/6/car,其中列出了分配给该预订的所有车辆。

在ValidateBooking中间件中,我使用6 eloquent函数验证上述网址中的预订ID Booking::find(6),但我想要的是,如果预订存在则将该对象传递给控制器​​,所以我不再在控制器中取回它。我不想为同一件事两次查询数据库。

我尝试了一些方法在中间件中将模型对象与$ request合并,但无法正确地在控制器上获取它。

我的中间件代码是:

<?php

namespace App\Http\Middleware\Booking;

use Closure;
use App\Booking\Booking;

class ValidateBooking
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $booking = Booking::find($request->booking_id);
        if (!$booking) {
            return redirect(route('booking.show', $request->booking_id));
        }
        $request->attributes->add(['bookingInstance' => $booking]);
        return $next($request);
    }
}

然后在控制器中取出它,如:

$request->get('bookingInstance')

如果我传递任何字符串值或其他东西,但它不能用于对象,它是否有效?请告知可能是最好的方法。

请指教?

3 个答案:

答案 0 :(得分:3)

您只能在请求对象上使用merge()函数。

public function handle($request, Closure $next)
{
    $booking = Booking::find($request->booking_id);
    if (!$booking) {
        return redirect(route('booking.show', $request->booking_id));
    }
    $request->merge(['bookingInstance' => $booking]);
    return $next($request);
}

除了使用已证明有效的$request->merge()之外,只需将模型对象添加到请求中,还可以帮助您访问控制器中的模型:

$request->booking = $booking;

唯一需要注意的就是确保从未有过一个名为booking的参数,以免覆盖它。

答案 1 :(得分:2)

我认为你想看的是Explicit Route Model bindings

如果您向RouteServiceProvider添加显式绑定,则可以在中间件和控制器中访问该参数。

// app/Providers/RouteServiceProvider.php

public function boot()
{
    parent::boot();
    Route::model('booking', \App\Booking\Booking::class);
}


// routes/web.php

Route::get('/booking/{booking}/car', 'BookingController@car')->middleware('booking.validate');


// app/Http/Middleware/ValidateBooking.php

public function handle($request, Closure $next)
{
    $booking = $request->booking;

    // ...

    return $next($request);
}


// app/Http/Controllers/BookingController.php

public function car(Request $request)
{
    dd($request->booking);
}

答案 2 :(得分:0)

这是你能做的。我曾经遇到过这个问题。

 public function handle($request, Closure $next)
{
    $booking = Booking::find($request->booking_id);
    if (!$booking) {
        return redirect(route('booking.show', $request->booking_id));
    }
    sesion()->put('bookingInstance', $booking);
    return $next($request);
}

这很简单。