路由模型绑定和软删除 - Laravel 4

10

当使用软删除和路由到模型绑定时,出现这样一种情况:如果注入的模型已被“软删除”,则无法查看它。

例如,我有一个工作模型。如果我“垃圾桶”其中一个模型,然后打开垃圾桶并尝试查看该工作模型,我会得到一个404资源未找到的错误。我通过以下方式使用Route::bind()函数解决了这个问题。

Route::bind('job', function($id, $route) {

    return Job::withTrashed()->find($id);
});
尽管这看起来有些不必要和有点儿傻...但是否有办法可以规避此问题,以便我可以使用非常简洁的单行绑定呢?
尽管这似乎是不必要和有点儿傻,但是否有一种方法可以解决这个问题,以便我可以使用非常简洁的单行绑定呢?
Route::model('job', 'Job');

1
我从来不知道软删除的存在 - 真是太棒了。我还没有测试过这个,但我认为你做得很对。文档说:“有时您可能希望为路由参数使用自己的解析器。”而在软删除后可能正是其中之一。我认为 Route::bind('foo',Foo) 所做的只是定义在您的路由中要使用的类或类型... 实际对象必须来自某个地方,对于您的单个作业,数据库调用并不是什么大问题。一个回调函数仍然非常优雅,想象一下如果没有 Laravel,需要多少过程性代码才能模仿那种行为。 - Ryan
1
好观点。在过程式编程中,这个简单的概念将是一个史诗般的任务... Laravel 让我重新爱上了 PHP。 - AndrewMcLagan
这个问题是“laravel route withtrashed”的第三个谷歌搜索结果,并为其提供了一个很好的答案 - 非常感谢! - damaxxed
3个回答

5

您在问题中提出的方案似乎可以解决它。

稍作调整,您可能需要指定要包括在废纸篓模型中的具体键。

例如,将正常路由模型绑定如下:

Route::model('job', 'Job');

同时定义另一个键名为'anyjob',在其中允许查询垃圾工作:

Route::bind('anyjob', function($id) {    
    return Job::withTrashed()->find($id);
});

然后对于那些不想包含已删除作业的路由,您只需引用job即可:
get('/jobs/{job}/edit', ['controller' => 'JobsController@edit']); // We don't want to be able to edit a trashed job.

只有在可以接受已删除的作业时,才针对anyjob绑定进行路由引用:

delete('/jobs/{anyjob}', ['controller' => 'JobsController@destroy']); // we could then forceDelete the trashed job for example as it'll be correctly injected in out our controller method

这可以避免在控制器方法中处理不应该存在的软删除模型。您可以指定确切的路由,以便接受任何作业,甚至仅处理已删除的作业。


4

Route::model() 方法使用模型的 find 方法,因此您可以简单地重写该方法以检索已删除的对象:

class Job extends Eloquent
{
    public static function find($id, $columns = array('*'))
    {
        return parent::withTrashed()->find($id, $columns);
    }
}

现在,您可以在没有闭包的情况下使用模型绑定。
Route::model('job', 'Job');

在你不想检索已经删除的对象时,使用find方法时要小心。


1
这似乎不适用于Laravel 5。它似乎在Router::model()函数中使用自己的键名。只是为了提醒其他使用Laravel 5的人而进行评论。 - John Mellor

1
除此之外,如果您已经构建了自己的特征和作用域,您可以在其中定义find函数。例如,我有一个“approvedTrait”,它的工作方式相同,但使用“approved”列来显示是否已由管理员批准某些内容。然后,我只需将其放入我的approvedTrait类中即可:
public static function find($id, $columns = array('*'))
{
    return self::withUnapproved()->find($id, $columns);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接