Laravel Change URL name detail - php

How do I make the post single URL like myweb.com/post-name instead myweb.com/post-id ? its works fine with posts id, but not with post name.
here my current route.
Route::get('/{id}', [App\http\Controllers\PostController::class, 'show']);
and here my controller.
public function show($id)
{
$post = post::find($id);
return view('detail', ['post' => $post]);
}
thank you.

That is because you are using the $id as the identifier to resolve the post object:
myweb.com/25
Then:
public function show($id) // $id = 25
{
$post = post::find($id); // find() search for the PK column, "id" by default
return view('detail', ['post' => $post]);
}
If you want to resolve the $post by a different field, do this:
public function show($name)
{
$post = post::where('name', $name)->first();
return view('detail', ['post' => $post]);
}
This should work for a route like this:
myweb.com/a-cool-post-name
As a side note, you could resolve the model automatically makin use of Route Model Binding.

Related

How to pass data to AppServiceProvider?

I'm trying to pass the $product variable in this controller to multiple view files.
function show($lang, $slug)
{
$product = Product::where('slug', $slug)->firstOrFail();
$mightAlsoLike = Product::where('slug', '!=', $slug)->MightAlsoLike()->get();
return view('shop_show')->with(['product' => $product, 'mightAlsoLike' => $mightAlsoLike]);
}
I'm using view composer in AppServiceProvider to pass the data to multiple view files but the problem is that the data in the variable needs the $slug param. how do I pass that $slug param to AppServiceProvider?
public function boot()
{
View::composer(['shop_show', 'partials/menus/right_bar'], function ($view) {
$site_slug = Route::current()->parameter('slug');
$product = Product::where('slug', $slug)->firstOrFail();
$view->with(['product' => $product]);
});
}
EDIT: the $site_slug variable returns null.
SOLVED: I defined my $slug param as {product} in my routes. changing the $site_slug variable to $site_slug = Route::current()->parameter('product'); fixed the issue.
You can use it like this
public function boot()
{
view()->share('categoryList', $categoriesList);
view()->share('packageList', $packageList);
view()->share('testList', $testList);
view()->share('testList1', $testList1);
}
I defined my $slug param as {product} in my routes. changing the $site_slug variable to $site_slug = Route::current()->parameter('product'); fixed the issue.

How rewrite DB::select to model with findOrFail in LARAVEL Controller

Hi i have REGION model but i dont know how rewrite this DB::select. I want it with findOrFail or something for ,,If i find this slug i show page if no i show 404
My web.php route
Route::get('/turnaje/{slug}', [RegionController::class, 'show']);
My Region Controller
public function show($slug)
{
$regions = DB::select('select * from regions where slug = ?', [$slug]);
$regions_list = DB::select('select * from regions');
return view('tournaments.show', [
'regions' => $regions,
'regions_list' => $regions_list,
]);
}
So you can use the model as a facade and write a similar query. I'm assuming you want an exception thrown when there is no region with that slug?
https://laravel.com/docs/8.x/eloquent#not-found-exceptions
public function show($slug)
{
$regions = Region::where('slug', $slug)->firstOrFail();
$regions_list = Region::all();
return view('tournaments.show', [
'regions' => $regions,
'regions_list' => $regions_list,
]);
}
You may want to handle the ModelNotFoundException
You have 2 options:
Changing route model binding form id to slug by defining getRouteKeyName function in your model:
public function getRouteKeyName()
{
return 'slug';
}
Using firstOrFail:
Region::where('slug', $slug)->firstOrFail();

Laravel redirect()->action not working and show missing parameters

PHP Version:7.2
Laravel Version:6.2
I am doing a simple project by laravel by article.
When I meet with redirect()->action, I am a little confused about that.
I want to pass a variable named id by redirect()->action but it does't work.
Error Message is Missing required parameters for [Route: blog/post.show] [URI: blog/post/{post}].
If I remove the variable name, only pass the variable value and it would work. I read the manual but still could not understand the reason. Could you help me explain the logic. Thank you. Below is the sample code.
Router.php
Route::group(['prefix' => 'blog',
'as' => 'blog/',
'namespace' => 'Blog'],
function(){
Route::resource('/post',"PostController");
});
PostController.php
Create new blog post ( wrong )
Couldn't understant why this does't work ? Variable name($id) is the same.
public function store(Request $request)
{
$post = new BlogPost;
$post->title = $title;
$post->content = $content;
$post->save();
return redirect()->action(
'Blog\PostController#show', ['id' => $post->id]
);
}
Create new blog post ( correct )
public function store(Request $request)
{
$post = new BlogPost;
$post->title = $title;
$post->content = $content;
$post->save();
return redirect()->action(
'Blog\PostController#show', [$post->id]
);
//Or 'Blog\PostController#show', $post->id
}
Show the new blog post
public function show($id)
{
$post = BlogPost::find($id);
if(! $post) {
abort(404);
}
$content = $post->content;
return view("blog.post", [
"title" => $post->title,
"content" => $content,
]);
}
Thank you
Here is code :
return redirect()->route('routename', ['id' => 1]);
You got the error message because you are using the Resource Route and it will automatic bind the Model with Route
For More Info please refer: https://laravel.com/docs/6.x/routing#route-model-binding
I encountered this error myself when trying to use a redirect()->action. Here's a simple example that will fail in just the same way.
class SimpleController extends Controller {
public function index() {
return redirect()->action([static::class, 'show'], ['id' => 7]);
}
public function show($id) {
// ... code goes here ...
}
}
And in the routes somewhere:
Route::resource('somethingsimpler', SimpleController);
The reason this fails is because default stub used by Route::resource for show is the same as the resource name. Have a read here: https://laravel.com/docs/9.x/controllers#actions-handled-by-resource-controller
Solution 1
We could change our original example to using 'somethingsimpler' instead of 'id'.
class SimpleController extends Controller {
public function index() {
return redirect()->action([static::class, 'show'], ['somethingsimpler' => 7]);
}
public function show($id) {
// ... code goes here ...
}
}
And in the routes somewhere:
Route::resource('somethingsimpler', SimpleController);
However, this seems to negate the whole purpose of using redirect()->action.
Solution 2
Reading further in the same document linked above, it seems you can set the resource name https://laravel.com/docs/9.x/controllers#restful-naming-resource-route-parameters.
class SimpleController extends Controller {
public function index() {
return redirect()->action([static::class, 'show'], ['id' => 7]);
}
public function show($id) {
// ... code goes here ...
}
}
And in the routes somewhere:
Route::resource('somethingsimpler', SimpleController)->parameters([
'somethingsimpler' => 'id'
]);
Solution 3 - Recommended
Reading the rest of the document, it becomes obvious that you can probably get away with not even naming the parameter.
class SimpleController extends Controller {
public function index() {
return redirect()->action([static::class, 'show'], [7]);
}
public function show($id) {
// ... code goes here ...
}
}
And in the routes somewhere:
Route::resource('somethingsimpler', SimpleController);

Route uses Slug, but id needed for function

I'm using slugs to navigate in my site, but I need the id connected to the slug for a function.
Function:
public function categories(Request $request, $slug)
{
$categories = Category::where('slug', $slug)->get();
$announcements = Announcement::where('category_id', $request->id)->paginate(5);
$category_lists = Category::all();
return view('announcements.index', compact('announcements', 'categories', 'category_lists'));
}
This is the function where I need to get the ID. $request->id isn't working since my $request->id returns 'null'. Is there any way to get the id that's connected to the slug/DB row?
If any more information is needed please tell me.
I've tried getting it with
$announcements = Announcement::where('category_id', Category::get(id))->paginate(5);
and things alike, nothing worked.
I suppose you override the getRouteKeyName in your Category model:
public function getRouteKeyName()
{
return 'slug';
}
Then you can get the Category like this with the route model binding:
public function categories(Request $request, Category $category)
{
$announcements = Announcement::where('category_id', $category->id)->paginate(5);
$category_lists = Category::all();
return view('announcements.index', compact('announcements', 'category', 'category_lists'));
}
Change your code to
$category = Category::where('slug', $slug)->first();
$announcements = Announcement::where('category_id', $category->id)->paginate(5);
if one category has one unique slug, just use first(), instead of get() and you can get the category object and use it.

Laravel 4 resource controller show($id) method problems

Does it have to be the 'id' column in database table which works fine for
show($id), edit($id) method in controller?
I want to replace $id with the value of 'post_id' column in database table, but it throws error: ModelNotFoundException
How can I fix it?
sample code:
database table:
id(int), post_id(varchar32), post_title(varchar32), post_content(text)
routes:
Route::resource('posts', 'PostsController');
PostsController:
public function show($id)
{
return View::make('posts.show');
}
When I visit http://localhost/posts/1
it should return the view of post which has id 1 in the table.
What if I what to return the view based on post_id value in the table?
Does it have to replace the parameter in show() or ?
In your PostsController you need to access the Post model to get the data from the db.
like this:
//PostsController
public function show($id) {
$post = Post::where('post_id', $id)->first();
return View::make('posts.show', compact('post'));
}
you can also use find
public function show($id) {
$post = Post::find($id);
return View::make('posts.show', compact('post'));
}

Categories