Проблема с отображением данных, которые я хочу удалить, с отношением «многие ко многим» в Laravel

У меня много отношений между пользователями и таблицей продуктов, и я настроил представление (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');
    }
}
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
0
89
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы определили следующий маршрут в файле.

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. Не забудьте добавить его!

Я изменил маршрут и ссылку, как вы мне сказали, и добавил return view('destroy')->with('product', $product); но он все еще показывает мне 404 не найденную страницу. Что я делаю неправильно?

mrmar 09.04.2019 21:37

Вы проверили вкладку сети в консоли разработчика вашего браузера, когда вы нажимаете на ссылку? Возвращает ли он 404 на правильный URL-адрес?

IGP 09.04.2019 22:33

URL запроса: admin.devel/уничтожить/1 Метод запроса: GET Код состояния: 404 Not Found . Это то, что возвращается, это правильный URL.

mrmar 09.04.2019 23:15

Маршруты удаления предназначены не только для APi, часть успокаивающих идей, лежащих в основе маршрутов Laravel, заключается в том, что вы можете вызывать патч, помещать и удалять.

ColinMD 09.04.2019 23:18

Хорошо, затем посмотрите, появляется ли этот маршрут в вашей консоли, когда вы запускаете php artisan route:list @ColinMD Да, через хак. размещение метода [at] в вашей форме не изменит того факта, что ваш браузер сделает запрос GET или POST. Он просто сообщает маршрутизатору Laravel: «Давайте представим, что это был запрос PUT, PATCH, DELETE».

IGP 09.04.2019 23:28

@IGF, поэтому Laravel был разработан таким, какой он есть, чтобы подделать правильный метод. Почему его нет в списке маршрутов?

ColinMD 09.04.2019 23:33

Доступные методы маршрутизатора Маршрутизатор позволяет регистрировать маршруты, которые реагируют на любую 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);

ColinMD 09.04.2019 23:35

Извините, этот комментарий немного сбил с толку. Я пытался спросить @Marko, появился ли маршрут в его списке, так как он все еще получает 404.

IGP 09.04.2019 23:41

@IGP Да, в моем списке есть маршрут, GET|HEAD | уничтожить/{$id} | product.destroy-форма | Приложение\Http\Controllers\HomeController@destroy

mrmar 10.04.2019 18:31

Я думаю, это потому, что для удаления продукта с новой страницы первое, что нужно сделать, это перейти на ту страницу, которую вы не делаете. Вместо этого вы переходите непосредственно к функции удаления, используя этот

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 и форму на свою страницу приветствия, я просто немного запутался, не могли бы вы уточнить, куда именно должен идти этот дополнительный маршрут получения?

mrmar 11.04.2019 16:12

Вам нужен только дополнительный маршрут, если вы хотите перейти на отдельную страницу для удаления. Если вы используете приведенный выше код, вам не понадобится дополнительный маршрут

ColinMD 12.04.2019 14:53

Другие вопросы по теме