Menu

48.跟踪话题更新

本节说明

  • 对应视频教程第 48 小节:This Thread Has Been Updated Since You Last Read It

本节内容

本节我们使用基本缓存来给用户一个小的可视提示:如果给定的话题自上次读取之后已经更新,那么我们更改话题标题为粗体进行提示。也就是说,我们在两种情况下均给出可视提示:

  1. 新发布的话题
  2. 已浏览过的话题有新回复

注:在第 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(),因为我们在其他地方也会用到该代码片段。

现在我们来运行测试:
file
测试通过,现在我们可以进行修改我们的前端显示:
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>
    .
    .

最后我们进行测试:
file

本文章首发在 Laravel China 社区
上一篇 下一篇
讨论数量: 0
发起讨论


暂无话题~