66.热门话题
- 本系列文章为
laracasts.com
的系列视频教程——Let's Build A Forum with Laravel and TDD 的学习笔记。若喜欢该系列视频,可去该网站订阅后下载该系列视频, 支持正版 ;- 视频源码地址:github.com/laracasts/Lets-Build-a-...;
- 本项目为一个 forum(论坛)项目,与本站的第二本实战教程 《Laravel 教程 - Web 开发实战进阶》 类似,可互相参照。
本节说明
- 对应视频教程第 66 小节:Trending Threads With Redis
本节内容
本节我们使用 Redis 来开发热门话题功能。首先我们安装 Redis:
$ composer require predis/predis
接着我们更改话题列表视图:
forum\resources\views\threads\index.blade.php
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row">
<div class="col-md-8">
@include ('threads._list')
{{ $threads->render() }}
</div>
<div class="col-md-4">
<div class="panel panel-default">
<div class="panel-heading">
Trending Threads
</div>
<div class="panel-body">
something here.
</div>
</div>
</div>
</div>
</div>
@endsection
刷新页面:
接下来新建测试:
forum\tests\Feature\TrendingThreadsTest.php
<?php
namespace Tests\Feature;
use Illuminate\Support\Facades\Redis;
use Tests\TestCase;
use Illuminate\Foundation\Testing\DatabaseMigrations;
class TrendingThreadsTest extends TestCase
{
use DatabaseMigrations;
public function setUp()
{
parent::setUp();
Redis::del('trending_threads');
}
/** @test */
public function it_increments_a_thread_score_each_time_it_is_read()
{
$this->assertEmpty(Redis::zrevrange('trending_threads',0,-1));
$thread = create('App\Thread');
$this->call('GET',$thread->path());
$trending = Redis::zrevrange('trending_threads',0,-1);
$this->assertCount(1,$trending);
$this->assertEquals($thread->title,json_decode($trending[0])->title);
}
}
由于我们使用了 Redis 系统,所以我们在运行测试之前需要清除缓存。我们建立了第一个测试:当未访问话题详情页面时,缓存为空;当访问了话题详情页面,缓存中会存在一条记录,同时,该记录的title
键对应的值即为该话题的值。我们接下来修改控制器,访问详情页时存入缓存:
forum\app\Http\Controllers\ThreadsController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Redis;
.
.
class ThreadsController extends Controller
{
.
.
public function show($channel,Thread $thread)
{
if(auth()->check()){
auth()->user()->read($thread);
}
Redis::zincrby('trending_threads',1,json_encode([
'title' => $thread->title,
'path' => $thread->path()
]));
return view('threads.show',compact('thread'));
}
.
.
}
运行测试:
接下来我们在页面显示热门话题。首先我们在控制器中取出分数最高的 5 个话题:
forum\app\Http\Controllers\ThreadsController.php
.
.
public function index(Channel $channel,ThreadsFilters $filters)
{
$threads = $this->getThreads($channel, $filters);
if(request()->wantsJson()){
return $threads;
}
$trending = array_map('json_decode',Redis::zrevrange('trending_threads',0,4));
return view('threads.index',compact('threads','trending'));
}
.
.
然后我们再显示在话题列表页:
forum\resources\views\threads\index.blade.php
.
.
<div class="col-md-4">
@if(count($trending))
<div class="panel panel-default">
<div class="panel-heading">
Trending Threads
</div>
<div class="panel-body">
<ul class="list-group">
@foreach($trending as $thread)
<li class="list-group-item">
<a href="{{ url($thread->path) }}">
{{ $thread->title }}
</a>
</li>
@endforeach
</ul>
</div>
</div>
@endif
</div>
.
.
查看效果: