Laravel技巧库

评论功能重构

此课程是收费课程,请先购买或加入会员后再访问。

现在的评论功能,和用户之间一点关系都还没有,这样是不正确的。用户登陆后,才能发表评论。如果没有登录呢,那就无法发表评论。

所以这里也不应该再有用户名和邮箱的input框了,直接应该就是当前登录用户发布的了。我们先来修改下comments表,删除nameemail,还要加上与users表关联用的user_id

migration

php artisan make:migration change_attributes_in_comments --table=comments
class ChangeAttributesInComments extends Migration
{
    public function up()
    {
        Schema::table('comments', function (Blueprint $table) {
            $table->integer('user_id');
            $table->dropColumn('name');
            $table->dropColumn('email');
        });
    }

    public function down()
    {
        Schema::table('comments', function (Blueprint $table) {
            $table->dropColumn('user_id');
            $table->string('name');
            $table->string('email');
        });
    }
}
php artisan migrate

跑完后,我们直接修改下数据库,给user_id加上对应的值。

user.php

// 一个 user有很多 comments
public function comments()
{
    return $this->hasMany('App\Models\Comment');
}

comment.php

class Comment extends Model
{
    //修改白名单,删掉`name` `email` 加上 `user_id`
    protected $fillable = ['issue_id', 'user_id', 'content'];

    //...

    //每一条评论,都是属于一个用户的
   xd}

user和comment的关联关系也要建立一下了。

view

 @foreach($comments as $comment)
    <li class="am-comment">
        <img src="{{$comment->user->avatar()}}" alt="" class="am-comment-avatar" width="48" height="48">

        <div class="am-comment-main">
            <header class="am-comment-hd">
                <div class="am-comment-meta">
                    <span class="am-comment-author">{{$comment->user->name}}</span>
                    {{$comment->created_at->diffForHumans()}}
                </div>
            </header>
            <div class="am-comment-bd"><p>{!! markdown($comment->content) !!}</p></div>
        </div>
    </li>
@endforeach

模板循环的地方,也许需要修改一下,因为现在是和评论是和user有关系了,所以这里的头像和用户名,也都要修改一下。

{!! Form::open(['route' => 'comments.store', 'class' => 'am-form']) !!}
{!! Form::hidden('issue_id', $issue->id) !!}
{!! Form::hidden('user_id', Auth::id()) !!}
<fieldset>
    <div class="am-form-group">
        {{ Form::textarea('content', null,  ['rows' => '5', 'placeholder' => '填写评论内容,支持markdown。']) }}
    </div>

    <p>
        {{ Form::submit('提交', ['class' => 'am-btn am-btn-default', 'id'=>'store-comment']) }}
    </p>
</fieldset>
{!! Form::close() !!}

这里的表单,就不用原生表单了,改用咱们之前学过的新写法。注意要加上一个隐藏的user_id
再来发布留言,一切都顺利。

n+1查询性能调优

功能通过debugbar,看到又有多条user的查询记录了,这还是之前所过的n+1查询导致的。解决方法还是加上with,再来看,也会变成了用where in来查询。

public function show(Issue $issue)
{
    $comments = $issue->comments()->with('user')->get();
    return view('issues.show', compact('issue', 'comments'));
}