#php #laravel #crud
#php #laravel #crud
Вопрос:
У меня есть отношения «многие ко многим» между таблицей пользователей и продуктов, и я настраиваю представление (welcome.blade.php ) что когда я нажимаю на название продукта, которое является ссылкой, предполагается, что оно перенаправляет меня на страницу, где находится моя форма удаления, чтобы я мог удалить этот конкретный продукт, но я получаю 404 ненайдена страница. Я подозреваю, что ошибка где-то в моих маршрутах, но, похоже, я не могу найти проблему. Также, когда я нажимаю на какой-либо продукт, на моем URL-адресе указано project/ destroy /1, что, я думаю, хорошо. Вот мой код:
web.php:
Route::get('/home', 'HomeController@index')->name('home');
Route::post('/store', 'HomeController@store')->name('store');
Route::delete('/destroy/{$id}', 'HomeController@destroy')->name('destroy');
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>
welcome.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 AppHttpControllers;
use AppProduct;
use IlluminateHttpRequest;
use IlluminateSupportFacadesAuth;
use IlluminateSupportFacadesDB;
class HomeController extends Controller
{
public function destroy(Product $product)
{
$product->users()->detach();
$product->delete();
return view('destroy');
}
}
Ответ №1:
Вы определили следующий маршрут в своем файле.
Route::delete('/destroy/{$id}', 'HomeController@destroy')->name('destroy');
Это создает маршрут УДАЛЕНИЯ. Маршруты УДАЛЕНИЯ предназначены для доступа к API. Ссылки в тегах привязки используют маршруты получения. Нажав на
<a href="{{ route('destroy' , $product->id) }}">{{ $product->files }}</a>
заставляет маршрутизатор пытаться сопоставить GET /destroy/{$id}
, который не определен, поэтому он выдает либо исключение, если включена отладка, либо 404, если нет. Вы можете увидеть это в действии, просмотрев вкладку «Сеть» в консоли разработчика вашего браузера.
Если вы не добавите другой маршрут GET, вы будете продолжать получать 404s.
Route::get('/destroy/{$id}', 'HomeController@destroy')->name('product.destroy-form');
заставит работать следующую ссылку.
<a href="{{ route('product.destroy-form' , $product->id) }}">{{ $product->files }}</a>
Кроме того, в методе destroy вы возвращаете представление без передачи каких-либо переменных, но, destroy.blade.php
похоже, используете $product
. Не забудьте добавить его!
Комментарии:
1. Я изменил маршрут и ссылку, как вы мне сказали, и добавил return view(‘destroy’)->with(‘product’, $product); но он по-прежнему показывает мне 404 не найденных страницы. Что я делаю не так?
2. Проверяли ли вы вкладку «Сеть» в консоли разработчика вашего браузера, когда нажимали на ссылку? Возвращает ли он 404 на правильный URL?
3. URL-адрес запроса: admin.devel/destroy/ 1 Метод запроса: ПОЛУЧИТЬ код состояния: 404 Не найден . Это то, что возвращается, это правильный URL.
4. Маршруты удаления предназначены не только для API, часть идей restful, лежащих в основе маршрутов Laravel, заключается в том, что вы можете вызывать patch, put и delete .
5. Хорошо, затем посмотрите, появляется ли этот маршрут в вашей консоли при запуске php artisan route:list @ColinMD Да, с помощью взлома. ввод метода [at] в вашу форму не изменит того факта, что ваш браузер выполнит запрос GET или POST. Он просто сообщает маршрутизатору Laravel: «Давайте представим, что это был запрос PUT, PATCH, DELETE».
Ответ №2:
Вы почти на месте, у вас просто слишком много шагов.
Хороший вызов формы и использование метода удаления, это абсолютно то, что вы должны делать
Однако, где вы ошибаетесь, так это в использовании ссылки для перехода на отдельную страницу с формой для удаления. Вам лучше использовать немного 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 на страницу, которая загружает форму, а затем вы можете отправить форму на этой странице для удаления.
Комментарии:
1. Я помещаю этот javascript и форму на свою страницу приветствия, я просто немного смущен, если вы можете уточнить, куда именно должен идти этот дополнительный маршрут get?
2. Вам нужен дополнительный маршрут, только если вы хотите перейти на отдельную страницу для удаления. Если вы используете приведенный выше код, вам не понадобится дополнительный маршрут
Ответ №3:
Я думаю, это потому, что для удаления продукта с помощью новой страницы первое, что нужно сделать, это перейти на ту страницу, которую вы не делаете. Вместо этого вы переходите непосредственно к функции удаления, используя это
Route::delete('/destroy/{$id}', 'HomeController@destroy')->name('destroy');
Вам нужно определить маршрут, который позволит вам сначала перейти на эту страницу, что вы можете сделать, создав такой маршрут:
Route::get('/delete/{$id}', 'HomeController@delete')->name('delete');
Вы должны создать новую функцию delete в HomeController, которая просто возвращает destroy.blade.php . Что-то вроде этого.
$product= Product::find($id);
return view('destroy')->with('product', $product);
где $id — это идентификатор продукта, а Product — модель, которую вы используете.