【问题标题】:Laravel redirect after destroy in resourceful controller在资源控制器中销毁后 Laravel 重定向
【发布时间】:2019-08-18 15:27:36
【问题描述】:

我想在删除一个项目后重定向到一个页面。我已经阅读了多篇关于此的帖子,包括 this one,但它似乎不起作用。

按下删除按钮后当前发生的情况是它进入了显示页面并给出了 404。那是因为该项目实际上已被删除,因此该页面不再工作。但根据我的代码,删除后应该重定向到路由trade.index

在路线/网络中

Route::resource('/trade', 'TradeController');

在 TradeController 中

public function destroy($id)
{
    $trade = Trade::findOrFail($id);
    $trade->delete();
    return redirect()->route('trade.index')->with('success', 'Trade deleted');
}

在视图中

<form action="{{ route('trade.destroy', $trade->id) }}" method="post">
    @csrf
    @method('DELETE')
    <button class="btn btn-lg btn-danger btn-block btn-animate" type="submit">
        <i class="far fa-trash-alt"></i> Delete
    </button>
</form>

来自路线:列表

DELETE | trade/{trade} | trade.destroy | App\Http\Controllers\TradeController@destroy                                
 | web,auth:web

我错过了什么?

根据下面的一些答案进行更新

首先,如果你像这样通过工匠创建一个足智多谋的控制器

php artisan make:controller TradeController -r

Laravel 在那个控制器中生成这个函数

public function destroy($id)
{
     //
}

所以这确实让我认为将它与$id 一起使用应该可以吗?

我也跑过

config:clear

cache:clear

确定。奇怪的是,我上面发布的原始代码现在有时可以工作(它可以正确删除和重定向),然后几次之后它就不起作用了(它确实删除了,但重定向不起作用)。如果我使用route('trade.destroy', ['id' =&gt; $trade-&gt;id]),那也是一样的。

另一件事是,对于 show() 我使用相同的原则。视图中使用的路线:

route('trade.show', $trade->id)

控制器中的方法:

public function show($id)
{
    $data = array(
        'trade'     => Trade::findOrFail($id),
    );
    return view('trade.show')->with($data);
}

如果我按照其中一个答案使用以下方法,它仍然不起作用。

public function destroy(Trade $trade)
{
    $trade->delete();
    return redirect()->route('trade.index')->with('success', 'Trade deleted');
}

【问题讨论】:

  • findOrFail() 可能会返回 404 响应。
  • 你能发布php artisan route:list输出吗?
  • @dparoli 我猜不是因为交易实际上被删除了。如果返回 404,那么 -&gt;delete() 将永远不会发生,对吧?表明删除操作正确执行,只是重定向没有发生。 @mdexp 我已经为销毁操作添加了 route:list 结果。
  • 对不起,如果我坚持,但你能尝试把 dd($trade) 放在 findOrFail($id) 之后,看看应用程序是否到达 dd()?
  • 只需将表单打开标签操作更改为:route('trade.destroy', ['id' => $trade->id])

标签: laravel


【解决方案1】:

您的路由参数名称{trade},因此您不能在控制器函数中将$id用作注入变量

您应该使用$trade 来匹配路由参数名称,否则findOrFail() 函数将无法找到任何内容,因为$idnull,即:

public function destroy($trade)
{
    $trade = Trade::findOrFail($trade);
    $trade->delete();
    return redirect()->route('trade.index')->with('success', 'Trade deleted');
}

隐式模型绑定甚至更好:

public function destroy(Trade $trade)
{
    $trade->delete();
    return redirect()->route('trade.index')->with('success', 'Trade deleted');
}

您可以阅读有关隐式绑定 here 的 laravel 文档。

【讨论】:

  • 如果它解决了您的问题,请考虑接受并支持答案
  • Your route parameter name is {trade} so you cannot use $id as injected variabe in the controller function. 我可能是错的,但如果我没记错的话,我认为如果您不需要隐式绑定,则可以将参数命名为您想要的任何名称(但不能是类型提示) .但是,如果您确实想使用隐式模型绑定,则必须将路由参数的名称与函数参数名称相匹配,并对模型进行类型提示,如您所说
  • 可能@mdexp你是对的,我没有自己尝试,我有给参数和注入变量起相同名称的习惯只是没有问题
  • 是的,我也这样做,对我来说确实更好,更易读
  • @dparoli 这似乎不起作用。我已经更新了我的答案。
【解决方案2】:

来自您的php artisan route:list 运行结果

DELETE | trade/{trade} | trade.destroy | App\Http\Controllers\TradeController@destroy | web,auth:web

传递给destroy() 方法的参数应绑定到名为trade 的模型。所以你必须为此设置路由模型绑定

首先进入以下文件:

app/Providers/RouteServiceProvider.php

并在您的 boot() 方法中包含模型绑定(如果不存在)

RouteServiceProvider.php

<?php

namespace App\Providers;

use App\Trade;
use Illuminate\Support\Facade\Route;

class RouteServiceProvider extends ServiceProvider
{
    public function boot()
    {
        parent::boot();

        Route::model('trade', Trade::class); // model binding
    }
}

然后,您现在可以正确定义删除路由方法

public function destroy(Trade $trade)
{
    $trade->delete();
    return redirect()->route('trade.index')->with('success', 'Trade deleted');
}

【讨论】:

  • 不需要显式绑定,隐式绑定类型提示变量就足够了,匹配的不是参数名和模型名,而是参数名和类型提示的变量名.
  • “在你的 boot() 方法中包含模型绑定如果它不存在”。如果绑定不存在,destroy(Trade $trade) 将不起作用。但是如果route::list 指定了trade/{id}destroy($trade) 将起作用。所以没有必要投反对票。
  • “您的删除函数需要一个 Trade 类的对象”这部分绝对是错误的,并且具有误导性,这是投反对票的原因。您应该仔细阅读我关于隐式绑定的答案中的链接。 laravel 中 90% 的隐式绑定问题是因为人们认为参数名称应该匹配模型名称,但它应该匹配类型提示的变量名称。
  • 如果路由参数与控制器的类型提示参数命名相同,隐式绑定仍然有效,并且控制器类型提示的类将用于检索模型实例
  • @dparoli,好的,我会删除那部分。但我认为过去的参数不应该与名称匹配。我认为路由定义中包含的参数名称应与模型绑定中的名称匹配。 destroy(Trade $anything) 非常有效。
猜你喜欢
  • 2017-12-18
  • 1970-01-01
  • 2014-09-05
  • 2015-07-29
  • 2018-04-03
  • 2021-06-01
  • 1970-01-01
  • 2016-07-23
  • 1970-01-01
相关资源
最近更新 更多