【问题标题】:Issues with Laravel 5's Route::bind()Laravel 5 的 Route::bind() 问题
【发布时间】:2014-12-15 02:41:20
【问题描述】:

我在试用 Laravel 5 时遇到了一点问题。

我按照 laracasts 中的整个教程进行操作,并尝试以与他们在那里完全相同的方式进行所有操作,只是我更改了模型、表和控制器的名称。

在某些时候 Route::bind() 停止工作,因此,现在当我尝试使用通配符访问路线时,会出现视图,但没有数据。

这是我的 routes.php

Route::bind('singers', function($slug, $route){
return App\Singer::whereSlug($slug)->first();
});

Route::resource('singers', 'SingerController', [
                                            'names' => [
                                                    'index' => 'singers_index',
                                                    'show' => 'singers_show',
                                                    'edit' => 'singers_edit',
                                                    'update' => 'singers_update',
                                                    'create' => 'singers_create',
                                                    'store' => 'singers_store',
                                                    'destroy' => 'singers_destroy',
                                                        ],
                                                ]);

这些是我的 SingerController

的一些 sn-ps
namespace App\Http\Controllers;

use Illuminate\Routing\Controller;
use Illuminate\Http\Request;
use App\Http\Requests\CreateSingerRequest;
use App\Singer;

class SingerController extends Controller {

    public $restful = true;

    public function __construct(Singer $singer){
        $this->singer = $singer;
    }

    public function index()
    {
        $singers = $this->singer->orderBy('id', 'DESC')->get();
        return view('singers.list',compact('singers'));
    }

    public function show(Singer $singer){
        return view('singers.show', compact('singer'));
    }

    public function edit(Singer $singer){
        return view('singers.edit', compact('singer'));
    }

    public function update(Singer $singer, Request $request){
        $singer->fill($request->input());
        $singer->save();
        return view('singers.show', compact('singer'));
    }

    public function create(){
        return view('singers.new');
    }

    public function store(Singer $singer, CreateSingerRequest $request){
        $singer->create($request->all());
        return redirect()->route('singers_index');
    }

    public function destroy(Singer $singer){
        $singer->delete();
        return redirect()->route('singers_index');
    }
}

现在。我尝试在 routes.php 中绑定变量 'singers' 的原因是因为他们在视频中这样做,这样,Controller 中的代码就更短了。它确实有效。然后我只是添加了破坏功能,它都停止了工作。 正如我所说,我可以看到视图、标签和其中的任何其他文本,但看不到我传递的数据,除了索引函数,因为我实际上是在函数本身中进行 Eloquent 搜索。

现在这是我的 show.blade.php 的 sn-p

<b>Full Name: </b> {{ $singer->name.' '.$singer->lastname }}
<br>
<b>Age: </b> {{ $singer->age }}
<br>
<b>Country: </b> {{ $singer->country }}
<br>
<br>
<p>
    <b>Bio: </b> {!! nl2br($singer->bio) !!}
</p>

{!! HTML::linkRoute('singers_edit', 'Update', [$singer->slug], ['class' => 'btn btn-primary']) !!}

{!! Form::open(['method'=>'DELETE', 'route'=>['singers_destroy', $singer->slug]]) !!}
    <div class="form-group">
        {!! Form::submit('Delete', ['class'=>'btn btn-danger']) !!}
    </div>
{!! Form::close() !!}

我的索引视图工作正常,其他视图只是表单,但是我传递变量的任何视图都不起作用,无论我是通过这样做传递它:

return view('singers.show',compact('singer'));

或者这个:

return view('singers.show')->with('singer',$singer);

回顾一下:

  • 索引 -> 很好。
  • 显示 -> 不会显示任何数据。
  • create -> 实际有效,新记录已保存。
  • edit -> 出现错误,因为通配符未发送到 控制器。

编辑

路径

  • 索引 (GET):/singers
  • 显示 (GET):/singers/{singers}
  • 创建 (GET):/singers/create
  • 存储 (POST):/singers
  • 编辑 (GET):/singers/{singers}/edit
  • 更新(补丁):/singers/{singers}
  • 销毁(删除):/singers/{singers}

请记住,{singers} 通配符在每种情况下实际上都是 $singer->slug,但是 Route::bind() 函数不允许我随意调用它。 当然,在第一个斜线出现之前 myserver/myproject/public

【问题讨论】:

  • 您使用什么网址进行显示和更新?
  • 显示路线 -> localhost/project/public/singers/{singers} 并编辑路线 -> localhost/project/public/singers/{singers}/edit 我将编辑我的帖子,以便您看到他们更好

标签: laravel model-binding blade laravel-routing laravel-5


【解决方案1】:

我很想知道当您重新编辑它时,您是否真的对其进行了编辑或使用了原件的副本。我刚刚做了同样的教程,完全被 Jeffrey 的魔法难倒了,但是在这里查看专门关于模型绑定的 API

http://laravel.com/docs/master/routing#route-model-binding

关键点是您的“通配符”必须在活动路由中触发,才能触发绑定匿名函数。

就我而言,使用原始命名法时,我有一个通配符 {slug},但后来他将其更改为 {song}。不知何故,我在歌曲中留下了我的,当我重新分配变量时没有效果。

$song = $this-&gt;song-&gt;whereSlug($slug)-&gt;first();

但是,一旦你做了路由器绑定,它就永远不会捕获,因为你使用的是 slug 作为你的通配符。

$router-&gt;get('songs/{slug}', 'SongsController@show');

所以当你把那个坏男孩绑在 Route::bind('song', function($slug) //The first literal "slug" MUST be a literal { //in the route we are searching!!! return \App\Song::whereSlug($slug)->first(); }); 它失败了,因为我的通配符过滤器从不匹配,但是把那首歌改成 slug 和 magic!

Route::bind('slug', function($slug) //The first literal "slug" MUST be a literal { //in the route we are searching!!! return \App\Song::whereSlug($slug)->first(); });

所以,我猜你在某处有一个 O 型,并在你的编辑中更正了它。它很微妙,尤其是使用这么多文字,并且没有代码类型提示。但没关系。我们不能都是杰弗里·韦。因此,如果您的绑定失败,请先仔细检查。

祝你好运。

【讨论】:

    【解决方案2】:

    我刚刚测试过了。

    Singer模特:

    <?php
    
    namespace App;
    
    use Illuminate\Database\Eloquent\Model;
    
    class Singer extends Model {
    
    }
    

    SingerController - 您提供的确切代码(此文件当然放在app\Http\Controllers 路径中。

    routes.php

    Route::bind('singers', function($slug, $route){
       return App\Singer::whereSlug($slug)->first();
    });
    
    Route::resource('singers', 'App\Http\Controllers\SingerController', [
        'names' => [
            'index' => 'singers_index',
            'show' => 'singers_show',
            'edit' => 'singers_edit',
            'update' => 'singers_update',
            'create' => 'singers_create',
            'store' => 'singers_store',
            'destroy' => 'singers_destroy',
        ],
    ]);
    

    如您所见,我在这里添加了完整的命名空间路径:'App\Http\Controllers\SingerController' 而不仅仅是SingerController

    我创建了简单的 Singer 表,字段只有 idslug - 仅用于测试(所以我只有这 2 列)并添加了 2 条记录:

    id slug
    1  abc
    2  def
    

    我创建的视图:

    list.blade.php:

    @foreach ($singers as $s)
    {{ $s->slug }}<br />
    @endforeach
    

    edit.blade.phpshow.blade.php(完全相同的代码):

    {{ $singer->slug }}
    {{ $singer->id }}
    

    现在当我跑步时:

    http://testpro/singers我得到结果:

    def
    abc
    

    正如预期的那样。

    当我跑步时:

    http://testpro/singers/abc/edit

    我明白了:

    abc 1
    

    正如预期的那样。

    当我跑步时:

    http://testpro/singers/def

    我明白了:

    def 2
    

    正如预期的那样。

    这里似乎一切正常。确保你按照我展示的方式使用它,它应该可以正常工作

    【讨论】:

    • 好吧,在我的例子中,我编辑了 RouteServiceProvider,所以我不需要添加命名空间。我将其编辑回原来的样子并尝试了您的示例,但它对我不起作用(这没有任何意义)。然后我把所有的东西都改回了我原来的帖子里的样子,一切都恢复了(这更没有意义了)。我似乎在缓存方面遇到了一些问题。所以我一直不得不在我的控制台中运行命令 php artisan clear-compiled && php artisan route:scan && php artisan route:cache。
    • 这些命令可能会弄乱我的应用程序的工作方式,但问题是,有时某些东西无法正常工作,并且我的路线出现错误,以及我更改错误的任何内容没有改变,所以我只是在编辑 routes.php 文件后运行这些命令,我​​实际上可以看到不同之处。就在一秒钟前,当我将我的代码编辑回我在开篇文章中的样子时,它又开始工作了,然后我运行这些命令只是为了看看发生了什么,它又停止工作了,然后我知道我做了什么,然后应用做出了应有的反应。
    • 我想我还是不明白关于路由缓存的一些东西。现在,感谢您花时间帮助我 Marcin。
    猜你喜欢
    • 1970-01-01
    • 2014-06-23
    • 2021-12-01
    • 2018-05-28
    • 2015-09-01
    • 2017-12-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多