I am trying to create a page where I can see all the people in my database and create edits on them. I made a form where I fill in the data from the database of certain fields.

I would like to navigate trough them by a Next and Previous button.

For generating the next step I have to take the ID larger than the current one to load the next profile.

For generating the previous step I have to take the ID smaller than the current one to load the previous profile.

My route:

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

Controller:

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);
    }

View: The buttons:

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

What is the best approach to get the current ID and increment it?

shareimprove this question
 
   
I can't answer the question unfortunately (though I'd probably also use your approach and then wonder if there's a better way as you are), but I think firstOrFail could end up being an issue: when the user gets to view the last model, rather than being able to see it they get a 404 page, just because there's no 'next' model available. – alexrussell Feb 20 '14 at 13:51

7 Answers 正确答案

Below are your updated controller and view files derived from @ridecar2 link,

Controller:

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);
}

View:

<a href="{{ URL::to( 'users/' . $previous ) }}">Previous</a>
<a href="{{ URL::to( 'users/' . $next ) }}">Next</a>
shareimprove this answer
 
   
I made a new version based on your version thanks! I still have some issues I made the snippet available here: laravel.io/bin/WWxL – Duikboot Feb 20 '14 at 16:17
1 
@Duikboot: You are passing $input variable to the view, not $previous or $next variables and in User::find()find needs to be in lowercase. Cross verify the code here. – user2581096 Feb 21 '14 at 4:05
   
Clean and simple. Thanks! – danboh May 17 '15 at 17:02
   
This is great, Thanks ! – Jordy Groote Oct 6 '16 at 13:38
   
Thanks Man, it's great – Malde Chavda Dec 16 '16 at 6:30
// 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();
shareimprove this answer
 
1 
Why do you use ->get() when you already have ->first()? – sulaiman Dec 8 '15 at 4:04
   
It was mistake , let me change that , thank you – Alireza Aboutalebi Dec 8 '15 at 7:03
   
your next function is actually previous, and your previous function is actually next ;) – rafamds Feb 2 '16 at 14:54
   
superb awesome peoples!! – msonowal Aug 17 '16 at 15:15
   
@rafaelmsantos thank you – Alireza Aboutalebi Aug 21 '16 at 8:11

Here's a link I found that should help: http://maxoffsky.com/code-blog/laravel-quick-tip-get-previous-next-records/

It looks like for next you want to use: $next = User::where('id', '>', $id)->min('id'); and have the view as: <a href="{{ URL::to( 'users/' . $next->id ) }}">Next</a>

Also don't forget to pass $next to the view.

shareimprove this answer
 

Simplest approach

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

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

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

Lazy approach :

// view
<a href="{{ 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);
});
shareimprove this answer
 

i developed the code.

it work all times, even if we don't have any next or prev post

public function nextPost($table, $id)
{
    $next = DB::table($table)->where('id', '>', $id)->orderBy('id','asc')->first();
    if(!$next)
        $next = DB::table($table)->orderBy('id','asc')->first();

    return $next;
}

public function prevPost($table, $id)
{
    $prev = DB::table($table)->where('id', '<', $id)->orderBy('id','desc')->first();
    if(!$prev)
        $prev = DB::table($table)->orderBy('id','desc')->first();
    return $prev;
}
shareimprove this answer
 

I understand the approach being taken here by user2581096 but I am not sure it is efficient (by any standards). We are calling the database 3 times for really no good reason. I suggest an alternative that will be way more efficient and scalable.

Do not pass the previous and next IDs to the view. This eliminates 2 unnecessary database calls.

Create the following routes:

users/{id}/next

users/{id}/previous

These routes should be used in the href attributes of the anchor tags

Add methods in the controller to handle each of the new routes you have created. For example:

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

This function will only be called when you actually click on the button. Therefore, the database call is only made when you need to actually look up the user.

shareimprove this answer
 
   
this is a good tip, but what if you want to show the prev & next records in the view of the current id ? ur current approach work if we need the prev & next as a simple pagination btns – ctf0 Oct 8 '16 at 21:40

in-case you want to retrieve the prev/next records along with their data, you can try

$id   = 7; // for example

$prev = DB::table('posts')->where('id', '<', $id)->orderBy('id','desc')->limit(1);
$next = DB::table('posts')->where('id', '>', $id)->limit(1);

$res = DB::table('posts')
        ->where('id', '=', $id)
        ->unionAll($prev)
        ->unionAll($next)
        ->get();

// now $res is an array of 3 objects
// main, prev, next
dd($res);

1- the query builder is usually much faster than eloquent.

2- with union we are now only hitting the db once instead of 3.


来自  https://stackoverflow.com/questions/21909706/laravel-previous-and-next-records

Previous, Next Post

PUBLISHED 1 YEAR AGO BY BLACKPEARL

Hello i had a problem with my next and previous buttons.Can someone help me ?

Its my method

public function art($id)
    {
        $post = Post::find($id);

        $previous = Post::where('id', '<', $post->id)->max('id');
        $next = Post::where('id', '>', $post->id)->min('id');

    return view('blog.show')->with('previous', $previous)->with('next', $next);
    }

My view

@extends('master')
@section('title', 'View a post')
@section('content')
    <div class="row">
                <h2>{!! $post->title !!}</h2>
                <img src="{!! asset($post->image) !!}" alt="" class="news-show">
                <p> {!! $post->content !!} </p>
    </div>
    <div class="clearfix"></div>
    <div class="row">
        <<a href="{{ URL::to( 'blog/' . $previous ) }}">Previous</a>
        <a href="{{ URL::to( 'blog/' . $next ) }}">Next</a>
    </div>
@endsection

and Route

Route::get('blog/{id?}','BlogController@art');

Why doesn't work ?

Best Answer(As Selected By blackpearl)
Prullenbak

Well, if it's the last post, then

$next = Post::where('id', '>', $post->id)->first();

would be Null. So in your view, you could do

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

Or, as @pmall pointed out:

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

that's a little bit cleaner.

Prullenbak

Your links are wrong.

Try

{{ URL::to( 'blog/' . $previous->id ) }}

and

{{ URL::to( 'blog/' . $next->id ) }}

Then, in your controller, you do

$next = Post::where('id', '>', $post->id)->first();

and you get the previous post in a similar way.

By the way, you should also check that there is a next or previous record. You might be viewing the first or last one.

 
pmall
 pmall
1 year ago(575,495 XP)

You should name your route and use the route('route.name', [$previous]) helper to generate urls.

 
Prullenbak

yes. As @pmaill is saying, something like this would be better:

Route::get('blog/{id}',[
    'as' => 'blog.show',
    'uses' => 'BlogController@art'
]);

Then, in your view, you build your links like this:

<a href="{{ route( 'blog.show', $previous->id ) }}">Previous</a>
 
pmall
 pmall
1 year ago(575,495 XP)

@Prullenbak quick tip, when you want to generate a route with the id of an object, you can pass the object only : route('show.blog', [$previous]).

 
Prullenbak

@pmall Does that also work if you don't make use of route-model binding? If that's the case: nice! Thanks for the tip :)

 
pmall
 pmall
1 year ago(575,495 XP)

Of course, route model binding is unrelated to url generation. When the url generator see a model as parameter it automagically takes its id. There is a method you can put in the model to return anything else than its id in this case (a slug for example) but I dont remember its name.

 
blackpearl

@Prullenbak can you tell me how check that is first or last post ? and fix this?

 
Prullenbak

Well, if it's the last post, then

$next = Post::where('id', '>', $post->id)->first();

would be Null. So in your view, you could do

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

Or, as @pmall pointed out:

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

that's a little bit cleaner.

 
blackpearl

thanks a lot, i appreciate this !

 
MWDeveloper

That was very helpful guys :)

 
dascorp
 dascorp
4 months ago(34,110 XP)

Hi, it works however I have couple of questions. what if we:

  • use UUID for id (we cannot compare id for greater or less than)
  • want to reduce amount of DB queries.
 

来自 https://laracasts.com/discuss/channels/laravel/previous-next-post

 

Custom order of Eloquent, get next/prev article?

PUBLISHED 2 YEARS AGO BY JASPERK

Hi, How do I get a previous / next article when there is a custom order?

# I'm ordering my Articles by publish_date in the overview
$articles = Article::orderBy("publish_date")->get();
# I find articles by their Slug
$article = Article::whereSlug("foobar")->first();

# I'm ordering my Projects by Title in the overview
$projects = Project::orderBy("title")->get();
# I find articles by their Slug
$project = Project::whereSlug("other")->first();

How can I find the next() and prev() article, based on the previous ordering?

Can I use the pagination in some way for this?

bestmomo
 bestmomo
2 years ago(368,210 XP)

Something like that :

$next = Article::orderBy("publish_date")->where('publish_date', '>', $article->publish_date)->first();
$previous = Article::orderBy("publish_date", 'desc')->where('publish_date', '<', $article->publish_date)->first();
 

来自 https://laracasts.com/discuss/channels/eloquent/custom-order-of-eloquent-get-nextprev-article