У меня много отношений между пользователями и таблицей продуктов, и я настроил представление (welcome.blade.php), которое, когда я нажимаю на название продукта, которое является ссылкой, должно перенаправлять меня на страницу, где моя форма удаления поэтому я могу удалить этот конкретный продукт, но я получаю 404 не найденную страницу. Я подозреваю, что ошибка где-то в моих маршрутах, но я не могу найти проблему. Также, когда я нажимаю на какой-либо продукт, мой URL-адрес говорит: проект/уничтожить/1, что я считаю хорошим. Вот мой код:
веб.php:
Route::get('/home', 'HomeController@index')->name('home');
Route::post('/store', 'HomeController@store')->name('store');
Route::delete('/destroy/{$id}', 'HomeController@destroy')->name('destroy');
уничтожить.blade.php:
<div class = "col-md-12">
<form action = "destroy/{{ $product->id }}" method = "POST">
@csrf
@method('DELETE')
<button type = "submit" class = "btn btn-danger">Delete</button>
</form>
</div>
добро пожаловать.blade.php:
@if ($products)
<table class = "table">
<thead>
<th>#</th>
<th>Product Name</th>
<th>Owner Of The Product</th>
<th>Created At</th>
</thead>
<tbody>
@foreach ($products as $product)
<tr>
<td>{{ $product->id }}</td>
<td>
<a href = "{{ route('destroy', $product->id) }}">{{ $product->files }}</a>
</td>
<td>
@foreach ($product->users as $user) {{ $user->name }}
@endforeach
</td>
<td>{{ date('M j, Y', strtotime($product->created_at)) }}</td>
</tr>
@endforeach
</tbody>
</table>
@endif
HomeController.php:
<?php
namespace App\Http\Controllers;
use App\Product;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
class HomeController extends Controller
{
public function destroy(Product $product)
{
$product->users()->detach();
$product->delete();
return view('destroy');
}
}
Вы определили следующий маршрут в файле.
Route::delete('/destroy/{$id}', 'HomeController@destroy')->name('destroy');
Это создает маршрут УДАЛЯТЬ. Маршруты УДАЛЯТЬ предназначены для доступа через API. Ссылки в тегах привязки используют маршруты ПОЛУЧАТЬ. Нажав на
<a href = "{{ route('destroy' , $product->id) }}">{{ $product->files }}</a>
заставляет маршрутизатор пытаться сопоставить ПОЛУЧАТЬ/destroy/{$id}
, который не определен, поэтому он выдает либо исключение, если отладка включена, либо 404, если нет. Вы можете увидеть это в действии, взглянув на вкладку сети в консоли разработчика вашего браузера.
Если вы не добавите еще один маршрут ПОЛУЧАТЬ, вы будете продолжать получать ошибки 404.
Route::get('/destroy/{$id}', 'HomeController@destroy')->name('product.destroy-form');
заставит следующую ссылку работать.
<a href = "{{ route('product.destroy-form' , $product->id) }}">{{ $product->files }}</a>
Кроме того, в методе уничтожения вы возвращаете представление без передачи каких-либо переменных, но в destroy.blade.php
вы, похоже, используете $product
. Не забудьте добавить его!
Вы проверили вкладку сети в консоли разработчика вашего браузера, когда вы нажимаете на ссылку? Возвращает ли он 404 на правильный URL-адрес?
URL запроса: admin.devel/уничтожить/1 Метод запроса: GET Код состояния: 404 Not Found . Это то, что возвращается, это правильный URL.
Маршруты удаления предназначены не только для APi, часть успокаивающих идей, лежащих в основе маршрутов Laravel, заключается в том, что вы можете вызывать патч, помещать и удалять.
Хорошо, затем посмотрите, появляется ли этот маршрут в вашей консоли, когда вы запускаете php artisan route:list @ColinMD Да, через хак. размещение метода [at] в вашей форме не изменит того факта, что ваш браузер сделает запрос GET или POST. Он просто сообщает маршрутизатору Laravel: «Давайте представим, что это был запрос PUT, PATCH, DELETE».
@IGF, поэтому Laravel был разработан таким, какой он есть, чтобы подделать правильный метод. Почему его нет в списке маршрутов?
Доступные методы маршрутизатора Маршрутизатор позволяет регистрировать маршруты, которые реагируют на любую HTTP-команду: Route::get($uri, $callback); Route::post($uri, $callback); Route::put($uri, $callback); Route::patch($uri, $callback); Route::delete($uri, $callback); Route::options($uri, $callback);
Извините, этот комментарий немного сбил с толку. Я пытался спросить @Marko, появился ли маршрут в его списке, так как он все еще получает 404.
@IGP Да, в моем списке есть маршрут, GET|HEAD | уничтожить/{$id} | product.destroy-форма | Приложение\Http\Controllers\HomeController@destroy
Я думаю, это потому, что для удаления продукта с новой страницы первое, что нужно сделать, это перейти на ту страницу, которую вы не делаете. Вместо этого вы переходите непосредственно к функции удаления, используя этот
Route::delete('/destroy/{$id}', 'HomeController@destroy')->name('destroy');
Вам нужно определить маршрут, который позволит вам сначала перейти на эту страницу, что вы можете сделать, создав такой маршрут:
Route::get('/delete/{$id}', 'HomeController@delete')->name('delete');
Вы должны создать новую функцию удаления в HomeController, которая просто возвращает файл destroy.blade.php. Что-то вроде этого.
$product= Product::find($id);
return view('destroy')->with('product', $product);
где $id — идентификатор продукта, а Product — модель, которую вы используете.
Вы почти у цели, просто у вас слишком большой шаг.
Хороший вызов формы и использование метода удаления, это абсолютно то, что вы должны делать.
Однако вы ошибаетесь, используя ссылку для перехода на отдельную страницу с формой для удаления. Вам лучше использовать небольшой javascript, чтобы ссылка отправляла скрытую форму по ссылке.
<a onclick = "document.getElementById('delete-form-{{$product->id}}').submit();}">{{ $product->files }}</a>
<form id = "delete-form-{{$product->id}}" action = "{{ route('destroy', ['id' => $product->id]) }}" method = "POST" style = "display: none;">
@csrf
@method('delete')
</form>
Вы можете использовать метод, который у вас есть, но вам нужен дополнительный запрос route::get на страницу, которая загружает форму, а затем вы можете отправить форму на этой странице для удаления.
Я поместил этот javascript и форму на свою страницу приветствия, я просто немного запутался, не могли бы вы уточнить, куда именно должен идти этот дополнительный маршрут получения?
Вам нужен только дополнительный маршрут, если вы хотите перейти на отдельную страницу для удаления. Если вы используете приведенный выше код, вам не понадобится дополнительный маршрут
Я изменил маршрут и ссылку, как вы мне сказали, и добавил return view('destroy')->with('product', $product); но он все еще показывает мне 404 не найденную страницу. Что я делаю неправильно?