14.用户可以筛选自己的话题

未匹配的标注

本节说明

  • 对应视频第 14 小节:A User Can Filter Threads By Username

本节内容

本节我们来实现根据用户来筛选话题的功能。首先运行一下测试:
file
会发现我们所有的测试都报错了,这是因为我们在上一节使用了 视图共享数据 :
forum\app\Providers\AppServiceProvider.php

. . public function boot() { Carbon::setLocale('zh'); \View::share('channels',\App\Channel::all()); } . .

boot()方法会在应用启动的最开始时就加载,在测试场景中,运行测试时,测试数据库中是不存在数据表的,所以就抛出了异常。我们改为使用 视图合成器

视图合成器是在渲染视图时调用的回调或者类方法。如果你每次渲染视图时都要绑定视图的数据,视图合成器可以帮你将这些逻辑整理到特定的位置。

forum\app\Providers\AppServiceProvider.php

. . public function boot() { Carbon::setLocale('zh'); \View::composer('*',function ($view){ $view->with('channels',Channel::all()); }); } . .

再次运行测试:
file
所以我们在更改了代码之后,要记得运行一下测试,确保代码无误。接下来按照惯例,建立新功能之前,先建立测试:
forum\tests\Feature\ReadThreadsTest.php

. . /** @test */ public function a_user_can_filter_threads_by_any_username() { $this->signIn(create('App\User',['name' => 'NoNo1'])); $threadByNoNo1 = create('App\Thread',['user_id' => auth()->id()]); $threadNotByNoNo1 = create('App\Thread'); $this->get('threads?by=NoNo1') ->assertSee($threadByNoNo1->title) ->assertDontSee($threadNotByNoNo1->title); } . .

运行测试会失败:
file
修改index()方法:
forum\app\Http\Controllers\ThreadsController.php

. . public function index(Channel $channel) { if($channel->exists){ $threads = $channel->threads()->latest(); }else{ $threads = Thread::latest(); } if($username = request('by')){ $user = \App\User::where('name',$username)->firstOrFail(); $threads->where('user_id',$user->id); } $threads = $threads->get(); return view('threads.index',compact('threads')); } . .

注:现在控制器中的代码比较粗糙,我们先让测试通过,在后面会进行重构,不要着急

运行测试:
file
系统界面:
file
修改导航栏,将这一功能显示出来:
forum\resources\views\layouts\app.blade.php

. . <div class="collapse navbar-collapse" id="app-navbar-collapse"> <!-- Left Side Of Navbar --> <ul class="nav navbar-nav"> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" aria-hidden="true" aria-expanded="false">Browse <span class="caret"></span> </a> <ul class="dropdown-menu"> <li><a href="/threads">ALL Threads</a> </li> <li><a href="/threads?by={{ auth()->user()->name }}">My Threads</a> </li> </ul> </li> <li><a href="/threads/create">New Thread</a></li> . .

file
运行测试,看我们是否破坏了功能:

$ APP_ENV=testing phpunit

file
根据报错信息可知,原因出在此行代码中:

<li><a href="/threads?by={{ auth()->user()->name }}">My Threads</a> </li>

若未登录,auth()->user()的值为null,因此会抛出上面的异常。修改一下代码:
forum\resources\views\layouts\app.blade.php

. . <div class="collapse navbar-collapse" id="app-navbar-collapse"> <!-- Left Side Of Navbar --> <ul class="nav navbar-nav"> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" aria-hidden="true" aria-expanded="false">Browse <span class="caret"></span> </a> <ul class="dropdown-menu"> <li><a href="/threads">ALL Threads</a> </li> @if(auth()->check()) <li><a href="/threads?by={{ auth()->user()->name }}">My Threads</a> </li> @endif </ul> </li> <li><a href="/threads/create">New Thread</a></li> . .

再次测试:
file

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。