Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Search object by slug and not by id

I'm a relative beginner with Laravel (using version 5.2.3) and have been working through tutorials on Laracasts and then doing a bit of my own experimenting.

I successfully set up a route that fetches an item from a table by its ID, as shown below

Route::get('/wiseweasel/{id}', 'WiseweaselController@singleArticle');

For simplicity, the controller simply dd's the article

public function singleArticle($id)
{
  $article = ww_articles::find($id);
  dd($article);
}

This works absolutely fine - I visit eg /wiseweasel/2 and get the contents of the record with id2.

So, I then wanted to use the slug field from the record instead of the id. Since I know the ID method was working, I've tried just modifying this route and controller (also tried creating anew, neither worked) So I now have:

Route::get('/wiseweasel/{slug}', 'WiseweaselController@singleArticle');

and

public function singleArticle($slug)
{
  $article = ww_articles::find($slug);
  dd($article);
}

The slug for the second record is "secondarticle". So, visiting the url /wiseweasel/secondarticle, I would expect to see the same record as previously dd'd out. Instead, I end up with null.

Even more oddly, using the original id route (/wiseweasel/2) still returns the record... when I have removed all trace of this from the routes and controller, so I would expect this to fail...

This is making me wonder if this could be some odd caching issue? I've tried

php artisan route:clear

in case the route was being cached. I've also tried restarting both Apache and MySql (I'm using XAMMP for both).

Still no luck though... not sure if I've misunderstood how something works or what's going on... so if anyone has any suggestions as to what I might have done wrong, or anything to try, I would be very grateful! :)

like image 558
Roxy Walsh Avatar asked Dec 27 '15 21:12

Roxy Walsh


2 Answers

You also have the option of using Route Model Binding to take care of this and inject the resolved instance into your methods.

With the new implicit Route Model Binding you can tell the model what key it should use for route binding.

// routes
Route::get('/wiseweasel/{article}', 'WiseweaselController@singleArticle');


// Article model
public function getRouteKeyName()
{
    return 'slug';
}

// controller
public function singleArticle(Article $article)
{
    dd($article);
}

Laravel Docs - Route Model Binding

like image 190
lagbox Avatar answered Oct 20 '22 15:10

lagbox


Laravel won't automatically know that for slug it should search record in different way.

When you are using:

$article = ww_articles::find($slug);

you are telling Laravel - find record of www_articles by ID. (no matter you call this id $slug).

To achieve what you want change:

$article = ww_articles::find($slug);

into

$article = ww_articles::where('slug', $slug)->first();

This will do the trick (for slug put the name of column in table in database). Of course remember that in this case slug should be unique in all records or you won't be able to get all the slugs.

like image 27
Marcin Nabiałek Avatar answered Oct 20 '22 16:10

Marcin Nabiałek