Laravel 5:路由模型绑定不识别对象

时间:2015-10-12 13:44:36

标签: php laravel laravel-5

我在search()

中有一个SubredditController方法
public function search(Request $request, Subreddit $subreddit)
{
    $query = $request->input('search');
    $subreddit = Subreddit::with('posts.votes')->with('moderators.user')->where('id', 24)->first();
    $posts = $subreddit->posts()->where('title', 'LIKE', '%' . $query . '%')->get();
    $isModerator = $subreddit->moderators()->where('user_id', Auth::id())->exists();
    $modList = Moderator::where('subreddit_id', '=', $subreddit->id)->get();

    return view('subreddit.search', compact('query', 'subreddit', 'posts', 'isModerator', 'modList'));
}

正如您所看到的,$subreddit正在从subreddit ID 24获取所有帖子并且查询有效。

但是当我用$subreddit->id替换24时,查询失败并给出null。

编辑:看起来它适用于$modList因为我在第一个变量24中对其进行了硬编码$subreddit,但仍然没有回答为什么$subreddit->id在同一个控制器的所有其他方法上工作正常时无法访问

编辑2 :我还尝试更改search路由以接受参数,例如此Route::post('search/{subreddit}'),但会出现错误NotFoundHttpException和网址重定向到localhost/reddit/public/search/%7Bsubreddit%7D它无法识别任何参数。

编辑3:如果我将search路由更改为Route::post('subreddit/{id}/search', ...)我没有收到任何错误,但$subreddit->id仍然无法访问且网址指向{{1 (%7个字符)

这些是我的绑定

subreddit/%7Bid%7D/search

我的路线

$router->model('subreddit', 'App\Subreddit');
$router->model('posts', 'App\Post');
$router->model('moderators', 'App\Moderator');

我发送搜索请求的视图(部分)

Route::resource('subreddit', 'SubredditController');

Route::resource('subreddit.moderators', 'ModeratorsController');

Route::get('mysubreddits', [
    'as' => 'mysubreddits',
    'uses' => 'SubredditController@mySubreddits'
]);

Route::post('search', ['as' => 'search', 'uses' => 'SubredditController@search']);

Route::resource('posts', 'PostsController');
Route::resource('votes', 'VotesController');
Route::resource('profile', 'ProfilesController');

1 个答案:

答案 0 :(得分:2)

您似乎假设模型的类型将自动以某种方式为您提供路线中的模型。但是,为了使路由模型绑定起作用,需要做一些事情:

  1. 您实际上需要在路线规范中包含参数。
  2. 您需要确保在URL中传递ID(或模型绑定功能中的任何字段)。
  3. 因此,鉴于您的代码,需要进行以下更改:

    路线:

    Route::post('search/{subreddit}', 'SubredditController@search')->name('search');
    

    这实际上为参数添加了一个占位符,并将其命名为与模型的路径绑定相同。

    (我也冒昧地重新排列该行没有笨拙的选项 - 数组语法,虽然取决于你的Laravel版本,这可能不适合你。)

    查看:

    {{ Form::open(['route' => ['search', $subreddit->getKey()]]) }}
    

    这可确保名为search的路由的第一个参数包含Subreddit的ID(密钥)值。

    这两件事一起,意味着URI最终会像/search/24一样被转换为SubredditController@search,其方法参数类型为Subreddit预先填充了真实模型(ID为24)。

    注意:如果您不希望在URI中使用ID,而是使用类似slug字段的ID,您仍然可以执行此操作 - 正常绑定路由,但在模型上定义{{1方法:

    getRouteKeyName

    然后只需将视图的public function getRouteKeyName() { return 'slug'; } 更改为:

    Form::open

    同样,这可能是5.1特定的,您可能正在使用5.0,这可能支持也可能不支持这样做。