Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

MahmoudMonem's avatar

How to get ID from URL slug

I have a url that looks like this

/courses/{slug}/units/{unit_id}

This page shows unit content of this specific course

What I am doing is : I added Next and Previous buttons for users to navigate between this specific course units.

The problem [ Users can keep clicking next next next going through al the Units to even other courses

in my Course.php


 public function getRouteKeyName(){
    return 'slug';
}

in my UnitsController :

public function show(Course $course, Unit $unit )
    {
        $course = Course::find($course);
        $previous_record = Unit::where('id', '<', $unit->id)->where('course_id', 1) ->orderBy('id','desc')->first();
        $next_record = Unit::where('id', '>', $unit->id)->where('course_id', 1)->orderBy('id')->first();

        dd($previous_record);
        return view('courses.units.show',  compact('course', 'unit', 'previous_record','next_record'));


    }

Notice Here : I was trying to just see if it will work by adding 1 for the course ID and it worked perfectly .. so what I need to do here is to replace this 1 with the a variable that gets course ID .. because when I use anything, I get error undefined variable.

$previous_record = Unit::where('id', '<', $unit->id)->where('course_id', 1) ->orderBy('id','desc')->first();
$next_record = Unit::where('id', '>', $unit->id)->where('course_id', 1)->orderBy('id')->first();

Course has many units Unit belongsTo course

Unit table has "course_id" column.

Would appreciate any input :)

0 likes
6 replies
Sergiu17's avatar

Try to change wildcards from your route, or arguments from show function

/courses/{course}/units/{unit}

public function show(Course $course, Unit $unit )

https://laravel.com/docs/8.x/routing#route-model-binding

Some notes here

// you have
public function show(Course $course, Unit $unit )
{
	$course = Course::find($course); // this line is useless
public function show(Course $course, Unit $unit )
{
	dd($course); // this will work, will return you an instance of course model
MahmoudMonem's avatar

Hello Sergiu .. thanks for your reply .. I have read the docs and watched many videos, but unfortunately couldn't spot a situation like this .. maybe it's too easy actually and my brain just can't get it. can you please give me more hints on what exactly needs to be changed in the wild cards ? Do I have to pass the course Id as Param ? .. would really appreciate more inputs

MahmoudMonem's avatar

@sergiu17 .. hello again.. actually I have watched this many times and watched now again and I'm implementing exactly what he is doing

  • I have defined {course} in route & function
  • I set getRouteKeyname to return slug instead if ID
  • I prevented Users from manually inputting Unit ID in the URL and is now returnig 403 through .htaccess, so this is not an issue

.. Jeffrey's example is tackling 1 table .. I don't have any problems with that and I can do it ... my problem now is that I have two params for 2 tables with relationship .2 Parameters passed in the URL . 1 is: course slug .. and one is : Unit id .. all i need is to get the course ID [ define it as a variable ] in the previous and next records queries. this will be enough to solve the passing through next units to even access other courses issue. by clicking next next next ...

the question is .. can I get the course ID variable with the current settings or no ? and if no where is exactly the problem ? should I change the slug parameters to be ID and if i did that, wouldn't this ID clash with Unit ID ? because when I tried something like that my loops got screwed. sorry for the long message.

automica's avatar
automica
Best Answer
Level 54

@mahmoudmonem

As you are passing in Course in your method arguments, then you don’t need

$course = Course::find($course);

as $course object has already been loaded.

You can get it’s id by getting it off the object

$id = $course->id

MahmoudMonem's avatar

@automica

 public function show(Course $course, Unit $unit )
    {
        $courseID = $course->id;
        $previous_record = Unit::where('id', '<', $unit->id)->where('course_id', $courseID) ->orderBy('id','desc')->first();
        $next_record = Unit::where('id', '>', $unit->id)->where('course_id', $courseID)->orderBy('id')->first();

        return view('courses.units.show',  compact('course', 'unit', 'previous_record','next_record'));

    }

It just did the job and now everything is working just as I want :D Thank you so much <3 !

1 like

Please or to participate in this conversation.