35.遗留的 Bug
- 本系列文章为
laracasts.com
的系列视频教程——Let's Build A Forum with Laravel and TDD 的学习笔记。若喜欢该系列视频,可去该网站订阅后下载该系列视频, 支持正版 ;- 视频源码地址:github.com/laracasts/Lets-Build-a-...;
- 本项目为一个 forum(论坛)项目,与本站的第二本实战教程 《Laravel 教程 - Web 开发实战进阶》 类似,可互相参照。
本节说明
- 对应视频第 35 小节:Squashing Bugs
本节内容
上一节我们改造了 点赞与取消点赞功能,但我们遗留了 Bug 未解决:
我们对回复进行了点赞与取消点赞的反复测试:当我们点赞的时候,activities
表中会增加一条记录,这当然是正确的;但是当我们取消点赞的时候,这条记录却没有删除,这就会导致我们访问个人页面时出现报错:
我们来追踪一下这个 Bug 产生的原因。我们在Favorite
模型中引入了RecordsActivity
Trait,而在RecordsActivity
中我们已经监听了模型的deleting
事件:
.
.
static::deleting(function ($model){
$model->activity()->delete();
});
.
.
回想一下,其实类似的问题我们在前面的章节中遇到过:我们删除话题的时候也会进行关联回复的删除,同时会把回复相关的动作流也进行删除。当时产生问题的原因是因为我们删除回复时,是通过sql
语句where
条件进行的批量删除,导致模型的deleting
事件没有被监听到。这次的原因类似:
forum\app\Favoritable.php
.
.
public function unfavorite()
{
$attributes = ['user_id' => auth()->id()];
$this->favorites()->where($attributes)->delete();
}
.
.
我们通过sql
语句进行删除,所以未监听到模型的deleting
事件。既然知道了原因,那么修复起来就很简单了:
.
.
public function unfavorite()
{
$attributes = ['user_id' => auth()->id()];
$this->favorites()->where($attributes)->get()->each->delete();
}
.
.
我们使用get()
获取模型实例的集合,并且每个模型实例分别调用delete()
方法。这样一来,favorite
模型的deleting
事件就会被监听到,相关的动作流也会被删除。现在我们删除之前的错误动作流数据,再次进行取消点赞操作:
但是我们仍有 Bug 待修复。如果我们对某个回复进行了点赞,但是该回复被删除,访问个人页面依然会报错:
我们清空activities
,favorites
表的数据之后再次测试:
但是我们发现清空之后的个人页面给人的体验不好,所以我们修改一下视图:
forum\resources\views\profiles\show.blade.php
.
.
@forelse($activities as $date => $activity)
<h3 class="page-header">{{ $date }}</h3>
@foreach($activity as $record)
@if(view()->exists("profiles.activities.{$record->type}"))
@include("profiles.activities.{$record->type}",['activity' => $record])
@endif
@endforeach
@empty
<p>There is no activity for this user yet.</p>
@endforelse
.
.
再次刷新页面:
接着修复 Bug:
forum\app\Favoritable.php
.
.
protected static function bootFavoritable()
{
static::deleting(function ($model) {
$model->favorites->each->delete();
});
}
.
.
我们还剩下最后一个小 Bug 需要修复:未登录用户可以看到点赞按钮。
修复它:
forum\resources\views\threads\reply.blade.php
.
.
@if(Auth::check())
<div>
<favorite :reply="{{ $reply }}"></favorite>
</div>
@endif
.
.