Laravel 8: Getting 404 “Not Found” Page While Trying To Delete User - php

I'm getting all users information at Blade, like this:
#foreach($users as $user)
<tr class="gradeX">
<td>{{ $user->name }}</td>
<td>{{ $user->email }}</td>
<td>{{ $user->role->name }}</td>
<td class="actions">
<i class="fa fa-pencil"></i>
<form method="POST" action="{{ route('users.destroy', $user->id) }}">
#csrf
#method('DELETE')
<button class="on-default remove-row btn-svg" title="Delete User"><i class="fa fa-trash-o"></i></button>
</form>
</td>
</tr>
#endforeach
As you can see, for deleting a custom user, I've added this:
<form method="POST" action="{{ route('users.destroy', $user->id) }}">
#csrf
#method('DELETE')
<button class="on-default remove-row btn-svg" title="Delete User"><i class="fa fa-trash-o"></i></button>
</form>
And at destroy method of the Controller:
public function destroy($id)
{
$user = User::findOrFail($id);
$photo = Photo::findOrFail($user->photo_id);
unlink(public_path() . $user->photo->path);
$photo->delete();
$user->delete();
return redirect('admin/users');
}
But now, whenever I try to delete the user from blade, I get 404 Not Found page. However the user still exists at the DB.
And when I add dd($id); at the Controller, I get this as result:
And user 14 exists at the table users just like below:
So what is going wrong here? How can I solve this issue and delete the user properly?
I would really appreciate any idea or suggestion from any of you guys...
Thanks in advance.

There are 2 options left what can be wrong, either you can’t find the user. Or you can’t find the photo. Based on the provided information it think there is no photo. The method findOrFail will return a 404 when the model is not found, see also https://laravel.com/docs/8.x/eloquent#not-found-exceptions.
So what you can do is add a dd before the photo check to see if the user is found. If that is true you can be sure it is the photo model. If that is the case, you should use Photo::find($user->photo_id).
After that you can wrap your unlink in an if statement where you Check if the photo model is not empty
public function destroy($id)
{
$user = User::findOrFail($id);
$photo = Photo::find($user->photo_id);
if (!empty($photo)) {
unlink(public_path() . $user->photo->path);
$photo->delete();
}
$user->delete();
return redirect('admin/users');
}

Related

How to display customer which have particular id?

I want to display user which have particular id. For example for id 1 should display customer which have id 2. Now redirect me to customers/1 but show empty page. What can I do that display user ?
route
Route::get('/', function () {
return redirect()->route('customers.index');
});
Route::get('/customers', '\App\Http\Controllers\CustomerController#index')->name('customers.index');
Route::get('/{id}', '\App\Http\Controllers\CustomerController#show')->name('customers.show');
controller
public function show(Customer $customer)
{
return view('show', compact('customer'));
}
view customers
a href=" {{ route('customers.show', ['id' => $customer->id]) }} ">
view customers/1
<tr>
<td>{{ $customer->first_name }}</td>
<td>{{ $customer->last_name }}</td>
<button type="submit" class="btn btn-danger">Delete</button>
<button type="submit" class="btn btn-success ms-1">Updated</button>
</tr>
Route: you can customize the route as you like, but the standard is as follows:
Route::get('/customers/{customer}', '\App\Http\Controllers\CustomerController#show')->name('customers.show');
CustomerController: when you do route model binding, it will do the findOrFail, so if you pass a customer that doesn't exist, you will get a 404 error automatically.
public function show(Customer $customer)
{
return view('customers.show', compact('customer'));
}
customers.show view: basic view to show data compacted from the controller
<tr>
<td>{{ $customer->first_name }}</td>
<td>{{ $customer->last_name }}</td>
</tr>
Simple, yet elegant :)
You can read how laravel prefers to structure routes here: https://laravel.com/docs/9.x/controllers#actions-handled-by-resource-controller
You can also go 1 step further, and let laravel do everything for you with the simple artisan command:
php artisan make:model Customer -mcr
Which will create, a resource, a migration, and a full resource controller.
Then in your web.php route:
Route::resource('customers', 'CustomerController');
Try change you code in routes file to:
Route::prefix('/customers')->group(function () {
Route::get('/customers', '\App\Http\Controllers\CustomerController#index')->name('customers.index');
Route::get('/{id}', '\App\Http\Controllers\CustomerController#show')->name('customers.show');
});

Route Model Binding Problem Does Not Seem To Be Working

I'm working with Laravel 8 and I have made a table like this at Blade:
<div class="card-body table-responsive p-0">
<table class="table table-hover">
<tr>
<th>Username</th>
<th>Email</th>
<th>Role</th>
<th>Actions</th>
</tr>
#foreach($roles as $role)
#if(count($role->users))
#foreach($role->users as $user)
<tr>
<td>{{ $user->name }}</td>
<td>{{ $user->email }}</td>
<td>{{ $role->name }} | {{ $role->label }}</td>
<td>
<form action="{{ route('levels.destroy' ,$user->id) }}" method="post">
#method('DELETE')
#csrf
<div class="btn-group btn-group-xs">
Edit
<button type="submit" class="btn btn-danger">Delete</button>
</div>
</form>
</td>
</tr>
#endforeach
#endif
#endforeach
</table>
</div>
And the result perfectly showing up:
But now I got problem with Edit & Delete buttons that I have specified $user->id as parameter for both of them.
And when I hover over the buttons I can see the user id properly defined:
But when it comes to edit method which is using Route Model Binding, it does not find the user:
public function edit(User $user)
{
dd($user->id); // return null
}
However if I do not use Route Model Binding and say this instead:
public function edit($id)
{
dd($id); // return 1
}
It properly shows the user id!
I don't know why the Route Model Binding not working here, so if you know what's going wrong or how to fix this issue, please let me know...
You are trying to access the User Model which in this case doesn't know what id is, so you should be passing the id of the user to the edit route using either Get by passing it to the url endpoint , so now you can get it like
public function edit($id)
{
dd($id); // return null
}
or by sending it as a POST form and get it like
public function edit(Request $request)
{
dd($request->id); // return null
}
I saw comments, your resource controller name is not matching with your variable name "$user".
You can look here on official laravel docs.
In your situation, this might help;
Route::resource('levels', LevelController::class)->parameters([
'levels' => 'user'
]);

How to remove id from http://localhost:8000/posts/2/edit when editing a data

I have a view that show some data and have edit feature, but when clicked edit button, user will be redirected to http://localhost:8000/posts/2/edit, I dont want post id appear in the URL, what should I do?
<table class="table table-bordered">
<tr>
<th width="20px" class="text-center">No</th>
<th>Title</th>
<th>Content</th>
<th width="280px" class="text-center">Action</th>
</tr>
#foreach ($posts as $post)
<tr>
<td class="text-center">{{ ++$i }}</td>
<td>{{ $post->title }}</td>
<td>{{ $post->content }}</td>
<td class="text-center">
<form action="{{ route('posts.destroy',$post->id) }}" method="POST">
<a class="btn btn-info btn-sm" href="{{ route('posts.show',$post->id) }}">Show</a>
<a class="btn btn-primary btn-sm" href="{{ route('posts.edit',$post->id) }}">Edit</a>
#csrf
#method('DELETE')
<button type="submit" class="btn btn-danger btn-sm" onclick="return confirm('Delete?')">Delete</button>
</form>
</td>
</tr>
#endforeach
</table>
here is the controller
public function edit(Post $post)
{
return view('posts.edit', compact('post'));
}
here is the route
Route::get('/', function () {
return view('welcome');
});
Route::resource('posts', App\Http\Controllers\PostController::class);
Auth::routes();
Thanks in advance
If you want to prevent users to edit posts that they did not create:
public function edit(Post $post)
{
if(Auth::user()->id != $post->user_id) {
throw new \Exception("Access denied", 403);
}
return view('posts.edit', compact('post'));
}
you need to use the Auth class offcourse:
use Illuminate\Support\Facades\Auth;
You need to do the same for the delete function
why you don't the id to appear in url. i can not see the reason to do that because there should be some unique key to edit the post. the only way i see is to add in the database a slug column and put it as unique. when adding a post put the title replacing space with '_' as a slug. make sure it is unique in validation. and in your edit and show code send the slug instead of the id.
route('posts.edit',$post->slug)
don't use dependency injection in controller
public function edit( $slug)
{
$post = Post::where('slug','=',$slug)->first();
return view('posts.edit', compact('post'));
}
hi
I think it will help you
your route will be like this:
Route::resource('posts', App\Http\Controllers\PostController::class)->except([
'edit'
]);
or
Route::resource('posts', App\Http\Controllers\PostController::class, ['only' => ['index', 'destroy', 'update' , 'create' , 'store']]);
or even you can write each route separately...
and write your edit route, separate :
Route::post('/post/edit', [App\Http\Controllers\PostController::class, "edit"])->name('post.edit');
delete #method('DELETE') from your blade and add this input to your blade :
<input type="hidden" name="post_id" value="{{$post->id}}" />
and change this :
public function edit(Post $post)
{
return view('posts.edit', compact('post'));
}
to this :
public function edit(Request $request)
{
$post_id = $request->post_id;
//write your code here
return view('posts.edit', compact('post'));
}

Laravel Delete record in a row is not as expected

I'm using resource controller to delete record in row by passing a collection into the view.
View:
<tbody>
#php $count=1; #endphp
#forelse ($products as $product)
<tr>
<td>{{ $count }}</td>
<td>{{ $product->name }}</td>
<td>{{ $product->slug }}</td>
<td>{{ $product->updated_at }}</td>
<td><span class="label label-success">Published</span></td>
<td>
<div class="btn-group">
View
Edit
Delete
<form id="delete-product" method="POST" action="{{ route('products.destroy', $product->slug) }}" style="display: none;">
#csrf
#method('DELETE')
</form>
</div>
</td>
</tr>
#php $count++; #endphp
#empty
<tr>
<td colspan="6">No products yet.</td>
</tr>
#endforelse
</tbody>
Controller:
public function products()
{
$products = Product::orderBy('created_at', 'desc')->paginate(10);
return view('vendor.products')->with('products', $products);
}
public function destroy(Product $product)
{
$product->delete();
return redirect('/account/products')->with('success', 'Product deleted successfully.');
}
When I click any of the "Delete" button, it deletes the last post (the first post in database, since it is sorted in descending).
Can someone tells me where it is wrong? I think initally the code work just fine, until I make some other modification and it is "magically" did not work as expected.
Edited:
route:
Route::prefix('/account')->group(function () {
Route::get('/products', 'AccountController#products');
Route::get('/corporate-info', 'AccountController#corporateInfo');
Route::get('/add-product', 'ProductController#create');
Route::get('/edit-product-{product}', 'ProductController#edit');
});
Route::resource('products', 'ProductController');
Product model:
public function getRouteKeyName()
{
return 'slug';
}
Ohh here is your issue :
Delete
<form id="delete-product" method="POST" action="{{ route('products.destroy', $product->slug) }}" style="display: none;">
#csrf
#method('DELETE')
</form>
You are giving the same id 'delete-product' to each form while looping therefore whenever you are
document.getElementById('delete-product').submit();
Its getting and submitting the form with the delete-product id which is the last one due to overriding issue to solve your issue :
Delete
<form id="delete-product-{{$product->slug}}" method="POST" action="{{ route('products.destroy', $product->slug) }}" style="display: none;">
#csrf
#method('DELETE')
</form>

Laravel 5 getting ID from URL

I have a table view in which I can click an button icon and redirect to another page carrying the id of the row that has been clicked.
#foreach ($patients as $patient)
<tr>
<td>{{ $patient->pID }}</td>
<td>{{ $patient->pName }}</td>
<td>{{ $patient->pAddress }}</td>
<td>{{ $patient->pBday }}</td>
<td>{{ $patient->pPhone}}</td>
<td>{{ $patient->pEcon }}</td>
<td>{{ $patient->pDreg }}</td>
<td></td>
<td>
<a href="{{ URL::to('visit/'.$patient->pID) }}">
<img src="../images/viewvisit.png" style="width:30px; height:30px;">
</a>
</td>
<td>
<a href="{{ URL::to('addeditvisit/'.$patient->pID) }}">
<img src="../images/visit.png" style="width:30px; height:30px;">
</a>
</td>
<td>
<a href="{{ URL::to('editpatient/'.$patient->pID) }}">
<img src="../images/update.png" style="width:30px; height:30px;">
</a>
</td>
<td>
<a href="{{ URL::to('deletepatient/'.$patient->pID) }}">
<img src="../images/delete.png" style="width:30px; height:30px;">
</a>
</td>
</tr>
#endforeach
what I want is to get the id from the URL and put it in a variable so that I can utilize it my other page.
I'm currently stuck with this controller function.
public function index(Request $request) {
$doctors = Doctor::where('dStatus', 0)
->lists('dName', 'dID');
$beds = Bed::where('bStatus', 0)
->lists('bName', 'bID');
$patient = Patient::patient();
// $uri = $request->path('patient');
return View::make('pages.addeditvisit', [
'doctors'=>$doctors,
'beds'=>$beds,
'patient'=>$patient->pID
]);
}
This is late. But for the benefit of others like me;
If you do not have to do it in a method like the answers above have shown, As of Laravel 5.0 (Not sure about previous versions), you can do
$request->route('id');
That returns the value of the id parameter on the route.
Or just use it within Blade: {{ request()->route('id') }}
Basically when you are defining the routes, you use something called route parameters, something like this
Route::get('/visit/{id}', 'Controller#someMethod');
This id will be available as a parameter in your handler funtion,
public function someMethod($id) {
// you have the id here
}
Simple example:
as link=> example.com/user/1
as rout=> Route::get('user/{id}', 'UserController#user');
as UserController function
public function user($id){
echo $id;
}
output => 1
The trick is to declare the url's structure at routes including the id, for example:
// {{ URL::to('editpatient/'.$patient->pID) }}
Route::get('editpatient/{patientId}', 'MyController#index');
Then, just inject the id in the controller's function:
public function index($patientId){
// $patientId is the variable from url
}
Please refer to the answered question for how to get a parameter from a route. But if you stumbled on this old Laravel thread looking for how to retrieve a model by its ID, the simplest way is to instantiate the model in the controller's request parameter:
Route::get('/retrieve_product/{product}', 'SearchController#getProduct');
Then over in your controller, you simply need:
use App\Product;
class SearchController extends Controller
{
public function getProduct( Product $product ) {
return $product;
}
}
That's it. No find, no where, no get, no first etc.
So, in this example, if you visit /retrieve_product/1 the first product is returned to you.
Route::get('post/user/{id}','ProductController#allpost')->where('id', '[0-9]+');
Controller
public function allpost($id)
{
$products = Product::where('uploadby', $id)->orderBy('created_at','desc')->paginate(5); <br>
return view('product.user_product')->with('products', $products);
}

Categories