首页 > 解决方案 > How to Pass slugged url to Controller in Laravel

问题描述

Hey Guys I am new to Laravel and I am currently trying to pass a slugged url into my controller, but I am having issues with it.

I have a table for categories and I have all the categories looped through and displayed on a view page (/posts). I listed all the categories on this view, so that when a user clicks on a category, they will be taken to a different page showing all posts belonging to that category(e.g, /posts/category/{categoryID}). I know I can get this done by passing the category id to the controller and finding the id to pass back to that view. However, I am trying to do something different. I am looking to pass the category name instead of the id to the controller. E.g, /posts/category/{category name}. But due to the fact that some categories are more than a word (e.g, Dry Cleaning), it has become a challenge for me. I had earlier slugged the URL for SEO purpose (e.g, /posts/category/{Str::str(categoryname)}) and from the web.php file, I created a get route.

Now, I'd like to fetch all posts relating to the category name passed in. The issue is that the category names are slugged.

Is there a way to remove the slug("-" or hyphen) from the name passed into the controller? So, instead of "Dry-cleaning", it will come back as "Dry cleaning" which matches the name in the database.

I am trying to avoid passing id to the url.

Thanks.

标签: phplaravelslug

解决方案


Good question.

There are a couple of approaches you can use to tackle this problem. I'll run through them for you.

1. Store the slug in the database

One option is to store the slug name within the database. Personally this is my favourite option as you don't need to do any string transformations. With this approach I would put a slug column in your categories table. Then you can use the Category eloquent model to search for a category with that slug.

2. Convert the slug to title case

The second option is to convert the slug to title case. You can do this by using Laravel's string class. For example:

$categoryName = Str::title($slug);

However there are a few issues with this approach. Firstly, when creating a slug the url will remove characters that are not safe, for example an apostrophe. This means if you have a pluralised category name it won't match when converting the slug back to title case.

Secondly, by using code to transform strings in order to match a record in the database you are at the mercy of the service class. While the functionality of Str::title is unlikely to change, it could in theory which could then mean you have to change code later on down the line.

Conclusion

Overall, I would recommend going with the first approach. You have much better data integrity and less chance of things going wrong further down the line. So if I were you I would create a new migration to add a slug column to your categories table and then populate each category with its own slug. Then search for a category based on the slug column when querying your eloquent model.


推荐阅读