48.跟踪话题更新
- 本系列文章为
laracasts.com
的系列视频教程——Let's Build A Forum with Laravel and TDD 的学习笔记。若喜欢该系列视频,可去该网站订阅后下载该系列视频, 支持正版 ;- 视频源码地址:github.com/laracasts/Lets-Build-a-...;
- 本项目为一个 forum(论坛)项目,与本站的第二本实战教程 《Laravel 教程 - Web 开发实战进阶》 类似,可互相参照。
本节说明
- 对应视频教程第 48 小节:This Thread Has Been Updated Since You Last Read It
本节内容
本节我们使用基本缓存来给用户一个小的可视提示:如果给定的话题自上次读取之后已经更新,那么我们更改话题标题为粗体进行提示。也就是说,我们在两种情况下均给出可视提示:
- 新发布的话题
- 已浏览过的话题有新回复
注:在第 2 种情况下,
Thread
模型的updated_at
字段会被更新。
首先我们建立测试:
forum\tests\Unit\ThreadTest.php
.
.
/** @test */
public function a_thread_can_check_if_the_authenticated_user_has_read_all_replies()
{
$this->signIn();
$thread = create('App\Thread');
tap(auth()->user(),function ($user) use ($thread){
// 对标题进行加粗显示
// 浏览话题
// 取消加粗
});
}
}
我们按照测试逻辑填充代码:
.
.
/** @test */
public function a_thread_can_check_if_the_authenticated_user_has_read_all_replies()
{
$this->signIn();
$thread = create('App\Thread');
tap(auth()->user(),function ($user) use ($thread){
$this->assertTrue($thread->hasUpdatesFor($user));
$user->read($thread);
$this->assertFalse($thread->hasUpdatesFor($user));
});
}
}
接下来我们需要添加增加判断话题是否被更新的逻辑——hasUpdatesFor()
和用户浏览话题的逻辑——read()
。首先,我们判断话题是否被更新:
forum\app\Thread.php
.
.
public function hasUpdatesFor($user)
{
// Look in the cache for the proper key
// compare that carbon instance with the $thread->updated_at
$key = $user->visitedThreadCacheKey($this);
return $this->updated_at > cache($key);
}
}
接着增加用户浏览话题的动作:
forum\app\User.php
.
.
public function read($thread)
{
cache()->forever(
$this->visitedThreadCacheKey($thread),
\Carbon\Carbon::now()
);
}
public function visitedThreadCacheKey($thread)
{
return $key = sprintf("users.%s.visits.%s",$this->id,$thread->id);
}
}
forum\app\Http\Controllers\ThreadsController.php
.
.
public function show($channel,Thread $thread)
{
if(auth()->check()){
auth()->user()->read($thread);
}
return view('threads.show',compact('thread'));
}
当一个已登录用户浏览某话题时,我们对登录用户调用read()
方法;在read()
方法中,我们记录当前浏览时间,并存入缓存;然后在hasUpdatesFor
中我们比较updated_at
话题更新时间和存入缓存的浏览时间,如果更新时间大于浏览时间,则返回true
。
注:为了避免重复,我们将获取
$key
的逻辑封装成visitedThreadCacheKey()
,因为我们在其他地方也会用到该代码片段。
现在我们来运行测试:
测试通过,现在我们可以进行修改我们的前端显示:
forum\resources\views\threads\index.blade.php
.
.
<h4 class="flex">
<a href="{{ $thread->path() }}">
@if($thread->hasUpdatesFor(auth()->user()))
<strong>
{{ $thread->title }}
</strong>
@else
{{ $thread->title }}
@endif
</a>
</h4>
.
.
最后我们进行测试: