Menu

66.热门话题

本节说明

  • 对应视频教程第 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

刷新页面:
file
接下来新建测试:
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;

    protected 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'));
    }
    .
    .
}

运行测试:
file
接下来我们在页面显示热门话题。首先我们在控制器中取出分数最高的 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>
                @endcan
            </div>
    .
    .

查看效果:
file

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


暂无话题~
刻意练习,每日精进。
0
点赞
248
浏览
0
讨论

维护者