Laravel route destroy return back issue - php

I have a step2 form which will store Order first in step1 then go to step2 page which the purpose is storing Aircon
When Click "trash icon" should go to route destroy but after return back()
Error: The GET method is not supported for this route. Supported methods: POST.
How to do correctly? passing $order in destroy ?
public function destroy(Aircon $aircon)
{
$aircon->delete();
return back();
}
public function store(Request $request, Order $order)
{
$order = Order::find($order->id);
$attributes = $this->validateAirCon();
$order->aircons()->create($attributes);
return view('pages.user.order-aircons.addAircon',compact('order'));
}
<form action="{{ route('aircon.store', $order) }}" method="post">
#csrf
{{--inputs... --}}
<button type="submit">aircon.store</button>
</form>
#forelse ($order->aircons as $aircon)
<table class="table">
<th>Model Number</th>
{{-- th.. --}}
<tr>
{{-- td... --}}
<td>
{{-- Delete Aircon --}}
<form action="{{ route('aircon.destroy', $aircon) }}" method="post">
#method('DELETE')
#csrf
{{-- button submit --}}
</form>
</td>
</tr>
</table>
#empty
<h1>no data</h1>
#endforelse

Use the route name:
public function destroy(Aircon $aircon)
{
$aircon->delete();
// Put the route name that you want to be redirected to that.
return redirect()->route('YOUR_ROUTE_NAME');
}

Problem solved
Use custom route to pass two parameters Aircon and Order
Route::delete('/aircon/delete/{aircon}/order{order}', [AirConController::class, 'delete'])->name('aircon.destroy');
public function delete(Aircon $aircon, Order $order)
{
$aircon->delete();
return view('pages.user.order-aircons.addAircon', compact('order'));
}

Related

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'
]);

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

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');
}

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'));
}

NotFoundHttpException in RouteCollection.php (line 179) when delete data from table

so, the view page already display all data. but there is an error "not found exception" when the delete button will be pressed. URL that showed in my browser when i press delete button is "http://localhost:8000/admin/hapusdataruang/69"
This is the view page
<table id="datatable-buttons" class="table table-striped table-bordered">
<thead>
<tr>
<th>ID Ruang</th>
<th>Nama Ruangan</th>
<th>Keterangan</th>
<th>Aksi</th>
</tr>
</thead>
<tbody>
#foreach($showruang as $rooms)
<tr>
<td>{{$rooms->id_ruang}}</td>
<td>{{$rooms->nm_ruang}}</td>
<td>{{$rooms->keterangan}}</td>
<td>
<form action="{{ url('/admin/hapusdataruang', $rooms->id_ruang) }}" method="post">
{{ csrf_field() }}
{{ method_field('DELETE') }}
Edit
<button class="btn btn-sm btn-danger" type="submit" onclick="return confirm('Yakin ingin menghapus data?')">Delete</button>
</form>
</td>
</tr>
#endforeach
</tbody>
This is the AdminController
public function destroyruang($id_ruang)
{
$ruang = Ruang::where('id_ruang',$id_ruang)->first();
$ruang->delete();
return redirect(url('/admin/dataruang'));
}
This is the admin route
Route::post('/hapusdataruang', 'AdminController#destroyruang', function () {
$users[] = Auth::user();
$users[] = Auth::guard()->user();
$users[] = Auth::guard('admin')->user();
//dd($users);
})->name('destroydataruang');
This is Ruang Model
use Illuminate\Database\Eloquent\Model;
namespace App;
class Ruang extends Model
{
protected $table = 'tr_ruang';
protected $primaryKey = 'id_ruang';
protected $dates = ['deleted_at'];
protected $fillable = ['keterangan','nm_ruang'];
}
The problem is in your routes file. You are submitting the form via a POST request to this url /admin/hapusdataruang, but you have {{ method_field('DELETE') }} in your form, so your route needs to be able to accept DELETE requests.
Your code:
Route::post('/hapusdataruang', 'AdminController#destroyruang', function () {
is for POST requests, not DELETE requests, so change it to:
Route::delete('/hapusdataruang', 'AdminController#destroyruang', function () {
change this code
Route::post('/hapusdataruang', 'AdminController#destroyruang', function () {
to
Route::delete('/hapusdataruang', 'AdminController#destroyruang', function () {
If You want to use the POST Request for deleting an entry from your database then you don't have to specify {{ method_field('DELETE') }} in your form, if you remove this from your form declaration then your existing route will work, but if you want to use the DELETE Request then you have to specify the Route as Route::delete('/yourpath','ControllerName#methodname');

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>

Categories