Registros anteriores y siguientes de Laravel

6 minutos de lectura

Estoy tratando de crear una página donde pueda ver a todas las personas en mi base de datos y editarlas. Hice un formulario donde completo los datos de la base de datos de ciertos campos.

Me gustaría navegar a través de ellos con los botones Siguiente y Anterior.

Para generar el siguiente paso, debo tomar una ID más grande que la actual para cargar el siguiente perfil.

Para generar el paso anterior tengo que tomar el ID más pequeño que el actual para cargar el perfil anterior.

Mi ruta:

Route::get('users/{id}','UserController@show');

Controlador:

public function show($id)
    {

        $input = User::find($id);

        // If a user clicks next this one should be executed.
        $input = User::where('id', '>', $id)->firstOrFail();



        echo '<pre>';

        dd($input);

        echo '</pre>';

        return View::make('hello')->with('input', $input);
    }

Vista:
Los botones:

<a href="https://stackoverflow.com/questions/21909706/{{ URL::to("users/' . $input->id ) }}">Next</a>

¿Cuál es el mejor enfoque para obtener la ID actual e incrementarla?

  • Desafortunadamente, no puedo responder la pregunta (aunque probablemente también usaría su enfoque y luego me preguntaría si hay una mejor manera que usted), pero creo firstOrFail podría terminar siendo un problema: cuando el usuario puede ver el último modelo, en lugar de poder verlo, obtiene una página 404, solo porque no hay un “próximo” modelo disponible.

    – alexrussell

    20 de febrero de 2014 a las 13:51

A continuación se muestra su controlador actualizado y los archivos de vista derivados del enlace @ridecar2,

Controlador:

public function show($id)
{

    // get the current user
    $user = User::find($id);

    // get previous user id
    $previous = User::where('id', '<', $user->id)->max('id');

    // get next user id
    $next = User::where('id', '>', $user->id)->min('id');

    return View::make('users.show')->with('previous', $previous)->with('next', $next);
}

Vista:

<a href="https://stackoverflow.com/questions/21909706/{{ URL::to("users/' . $previous ) }}">Previous</a>
<a href="https://stackoverflow.com/questions/21909706/{{ URL::to("users/' . $next ) }}">Next</a>

  • Hice una nueva versión basada en tu versión gracias! Todavía tengo algunos problemas. Hice el fragmento disponible aquí: laravel.io/bin/WWxL

    – Duikboot

    20 de febrero de 2014 a las 16:17

  • @Duikboot: Estás pasando $input variable a la vista, no $previous o $next variables y en User::find(), encontrar tiene que estar en minúsculas. Verifique el código de forma cruzada aquí.

    usuario2581096

    21 de febrero de 2014 a las 4:05


  • Limpio y sencillo. ¡Gracias!

    – danboh

    17 mayo 2015 a las 17:02

  • Esto es genial, gracias!

    – Pato de goma1337106092

    06/10/2016 a las 13:38

  • Gracias hombre, es genial

    – Malde Chavda

    16 de diciembre de 2016 a las 6:30

avatar de usuario
Alireza Aboutalebi

// in your model file
public function next(){
    // get next user
    return User::where('id', '>', $this->id)->orderBy('id','asc')->first();

}
public  function previous(){
    // get previous  user
    return User::where('id', '<', $this->id)->orderBy('id','desc')->first();

}
// in your controller file
$user = User::find(5); 
// a clean object that can be used anywhere
$user->next();
$user->previous();

  • su próxima función es en realidad anterior, y su función anterior es en realidad la siguiente;)

    – Rafael Morais

    2 de febrero de 2016 a las 14:54

  • Excelentes pueblos impresionantes !!

    – msonowal

    17 de agosto de 2016 a las 15:15

  • ¡Gracias! Esa es la mejor manera si usamos slug en lugar de id 🙂

    – Iván

    06/03/2017 a las 23:10

  • Esto solo funcionará si estamos usando orderBy con id si ordenamos con otra columna, ¿entonces?

    – Sagar Naliyapara

    3 de mayo de 2017 a las 5:54

  • @SagarNaliyapara ¡necesita una identificación válida para ordenar!

    – Alireza Aboutalebi

    3 mayo 2017 a las 11:32

avatar de usuario
Shreyansh Panchal

En tus App\Models\User.php

...
protected $appends = ['next', 'previous'];

public function getNextAttribute()
{
    return $this->where('id', '>', $this->id)->orderBy('id','asc')->first();
}

public function getPreviousAttribute()
{
    return $this->where('id', '<', $this->id)->orderBy('id','asc')->first();
}

En su controlador, simplemente puede hacer esto:

public function show(User $user)
{
    return View::make('users.show')
    ->with('user', $user)
    ->with('previous', $user->previous)
    ->with('next', $user->next);
}

  • y puede usar $user->next o $user->previous si tu appends en modelo

    – historia ks

    9 de marzo a las 2:32

  • Para el getPreviousAttribute() tiene que ser ->orderBy('id','desc')

    – shahabphp

    15 de mayo a las 12:32

Entiendo el enfoque adoptado aquí por el usuario 2581096, pero no estoy seguro de que sea eficiente (según cualquier estándar). Estamos llamando a la base de datos 3 veces sin ninguna buena razón. Sugiero una alternativa que será mucho más eficiente y escalable.

No pase los ID anterior y siguiente a la vista. Esto elimina 2 llamadas de base de datos innecesarias.

Crea las siguientes rutas:

usuarios/{id}/siguiente

usuarios/{id}/anterior

Estas rutas deben usarse en los atributos href de las etiquetas de anclaje

Agregue métodos en el controlador para manejar cada una de las nuevas rutas que ha creado. Por ejemplo:

 public  function getPrevious(){
        // get previous  user
        $user = User::where('id', '<', $this->id)->orderBy('id','desc')->first();
        return $this->show($user->id);
    }

Esta función solo se llamará cuando haga clic en el botón. Por lo tanto, la llamada a la base de datos solo se realiza cuando necesita buscar al usuario.

avatar de usuario
saurav sharma

Para obtener la publicación siguiente y anterior podemos usar max y min funciones en identificación del modelo en laravel. aquí hay un ejemplo para obtener esto
https://usingphp.com/post/get-next-and-previous-post-link-in-laravel
El controlador:

public function post($id)
{
    $post = Post::find($id);
    $previous = Post::where('id', '<', $post->id)->max('id');
    $next = Post::where('id', '>', $post->id)->min('id');
    return view( 'post', compact( 'post', 'next', 'previous' ));
}

La vista:

@if($next)
   <a href="{{ route( 'blog.show', $next->id ) }}">{{$next->title}}</a>
@endif
@if($previous)
   <a href="{{ route( 'blog.show', $previous->id ) }}">{{$previous->title}}</a>
@endif

avatar de usuario
paseocar2

Aquí hay un enlace que encontré que debería ayudar: http://maxoffsky.com/code-blog/laravel-quick-tip-get-previous-next-records/

Parece que para el próximo que desea utilizar: $next = User::where('id', '>', $id)->min('id'); y tener la vista como: <a href="https://stackoverflow.com/questions/21909706/{{ URL::to("users/' . $next->id ) }}">Next</a>

Tampoco olvides pasar $next a la vista

avatar de usuario
Alejandro Butynski

Enfoque más simple

// User.php
public static function findNext($id)
{
    return static::where('id', '>', $id)->first();
}

// UserController.php
$nextUser = User::findNext($id);

// view
<a href="https://stackoverflow.com/questions/21909706/{{ URL::to("users/' . $nextUser->id ) }}">Next</a>

Enfoque perezoso:

// view
<a href="https://stackoverflow.com/questions/21909706/{{ URL::to("users/' . $input->id . '/next') }}">Next</a>

// routes.php (should be optimized, this is just to show the idea)
Route::get('users/{user}/next', function($id) {
    $nextUser = User::findNext($id);
    return Redirect::to('user/' . $id);
});

¿Ha sido útil esta solución?