Laravel: recupera el modelo enlazado de la solicitud

3 minutos de lectura

Avatar de usuario de Phil Cross
phil cruz

¿Hay alguna manera fácil de recuperar el modelo vinculado a la ruta dentro de una Solicitud?

Quiero actualizar un modelo, pero antes de hacerlo, quiero realizar algunas verificaciones de permisos usando las Solicitudes authorize() método. Pero solo quiero que el propietario del modelo pueda actualizarlo.

En el controlador, simplemente haría algo como esto:

public function update(Request $request, Booking $booking)
{
    if($booking->owner->user_id === Auth::user()->user_id)
    {
       // Continue to update
    }
}

Pero estoy buscando hacer esto dentro de la Solicitud, en lugar de hacerlo dentro del controlador. Si lo hago:

dd(Illuminate\Http\Request::all());

Solo me da las propiedades de la forma escalar (como _method y así sucesivamente, pero no el modelo).

Pregunta

Si vinculo un modelo a una ruta, ¿cómo puedo recuperar ese modelo desde una solicitud?

Muchas gracias de antemano.

  • Como actualización de esta pregunta: es posible que desee consultar Laravel’s autorización componente. ¡Parece perfecto para tus necesidades!

    – Martín Bean

    7 de noviembre de 2015 a las 11:52


Avatar de usuario de Martin Bean
frijol martín

¡Absolutamente! Es un enfoque que incluso uso yo mismo.

Puede obtener la ruta actual en la solicitud y luego cualquier parámetro, así:

class UpdateRequest extends Request
{
    public function authorize()
    {
        // Get bound Booking model from route
        $booking = $this->route('booking');

        // Check owner is the currently authenticated user
        return $booking->owner->is($this->user());
    }
}

A diferencia de la respuesta de smartman (ahora eliminada), esto no genera otra consulta de búsqueda si ya ha recuperado el modelo a través del enlace ruta-modelo.

Sin embargo, personalmente también usaría un política aquí en lugar de poner comprobaciones de autorización en las solicitudes de formulario.

  • ¡Gracias por la respuesta! ¡Sabía que probablemente iba a ser algo tan simple como eso, pero no pude resolverlo yo mismo! Aceptaré cuando me lo permita 🙂

    – Phil Cruz

    21 de abril de 2015 a las 14:35

  • wow, ¡no conocía esta característica de Laravel! ¡Aprenda algo nuevo cada día! 🙂

    – Limón Monte

    21 de abril de 2015 a las 14:41

  • Si entendí correctamente obtener el parámetro de ruta, ¿laravel entiende automáticamente a qué instancia está vinculado este parámetro?

    – Harry Geo

    21 de abril de 2015 a las 14:47

  • @akad0 Si tiene una ruta definida así: Route::get('bookings/{booking}');luego obteniendo el booking el parámetro produciría el valor de lo que sea que esté vinculado al {booking} simbólico.

    – Martín Bean

    21 de abril de 2015 a las 14:49

  • @MartinBean ¿Solo el valor o la instancia completa? Mirando tu código que estás usando $booking como una instancia y accediendo a su función relacionada owner() para recuperar el user_id atributo. EDITAR: ¿O simplemente está pasando la instancia como valor?

    – Harry Geo

    21 de abril de 2015 a las 14:52


Una vez que hiciste tu enlace explícito (https://laravel.com/docs/5.5/routing#route-model-binding) en realidad puedes obtener tu modelo directamente con $this.

class UpdateRequest extends Request
{
    public function authorize()
    {
        return $this->booking->owner->user_id == $this->booking->user()->id;
    }
}

¡Aún más limpio!

Para agregar a la respuesta de Martin Bean, puede acceder a la instancia enlazada usando solo route($param):

class UpdateRequest extends Request
{
    public function authorize()
    {
        $booking = $this->route('booking');

        return $booking->owner->user_id == $this->user()->id;
    }
}

Nota: Esto funciona en Laravel 5.1. No he probado esto en versiones anteriores.

Si no está utilizando el bindings middleware o si desea acceder al límite $model en cualquier otro lugar aparte de FormRequest y Controller puedes usar lo siguiente:

$book = app(Book::class)->resolveRouteBinding(request()->route('book'));

¿Ha sido útil esta solución?