31.删除回复

未匹配的标注

本节说明

  • 对应视频第 31 小节:Authorized Users Can Delete Replies

本节内容

本节我们完成删除回复的功能。首先新建测试:
forum\tests\Feature\ParticipateInForumTest.php

    .
    .
    /** @test */
    public function unauthorized_users_cannot_delete_replies()
    {
        $this->withExceptionHandling();

        $reply = create('App\Reply');

        $this->delete("/replies/{$reply->id}")
            ->assertRedirect('login');
    }
}

接着建立路由:
forum\routes\web.php

.
.
Route::delete('/replies/{reply}','RepliesController@destroy');
Route::post('/replies/{reply}/favorites','FavoritesController@store');
.

虽然我们现在还没有destroy()方法,但是如果我们运行测试,仍然会通过。因为我们使用了中间件$this->middleware('auth'),未登录用户会直接被重定向至登录页面,所以我们的测试会通过:
file
现在我们已经测试了未登录用户,接下来加上已登录但无权限用户的测试:

    .
    .
    /** @test */
    public function unauthorized_users_cannot_delete_replies()
    {
        $this->withExceptionHandling();

        $reply = create('App\Reply');

        $this->delete("/replies/{$reply->id}")
            ->assertRedirect('login');

        $this->signIn()
            ->delete("/replies/{$reply->id}")
            ->assertStatus(403);
    }
}

添加destroy()方法:
forum\app\Http\Controllers\RepliesController.php

<?php

namespace App\Http\Controllers;

use App\Reply;
use App\Thread;

class RepliesController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth');
    }

    public function store($channelId,Thread $thread)
    {
        $this->validate(request(),['body' => 'required']);

        $thread->addReply([
            'body' => request('body'),
            'user_id' => auth()->id(),
        ]);

        return back()->with('flash','Your reply has been left.');
    }

    public function destroy(Reply $reply)
    {
        if($reply->user_id != auth()->id()){
            return response([],403);
        }

        $reply->delete();

        return back();
    }
}

运行测试:
file
现在我们来测试有权限的用户:
forum\tests\Feature\ParticipateInForumTest.php

    .
    .
    /** @test */
    public function authorized_users_can_delete_replies()
    {
        $this->signIn();

        $reply = create('App\Reply',['user_id' => auth()->id()]);

        $this->delete("/replies/{$reply->id}")->assertStatus(302);

        $this->assertDatabaseMissing('replies',['id' => $reply->id]);
    }
}

运行测试:
file
我们实际上测试了两个动作:删除跟重定向。现在测试代码已经编写完成,接下来让我们进行重构:使用Policy来做权限控制。首先新建Policy

$ php artisan make:policy ReplyPolicy

forum\app\Policies\ReplyPolicy.php

<?php

namespace App\Policies;

use App\User;
use App\Reply;
use Illuminate\Auth\Access\HandlesAuthorization;

class ReplyPolicy
{
    use HandlesAuthorization;

    public function update(User $user, Reply $reply)
    {
        return $reply->user_id == $user->id;
    }
}

注册Policy
forum\app\Providers\AuthServiceProvider.php

.
.
protected $policies = [
    'App\Thread' => 'App\Policies\ThreadPolicy',
    'App\Reply' => 'App\Policies\ReplyPolicy',
];
.
.

应用Policy
forum\app\Http\Controllers\RepliesController.php

    .
    .
    public function destroy(Reply $reply)
    {
        $this->authorize('update',$reply);

        $reply->delete();

        return back();
    }
}

运行全部测试:
file
我们还有最后一步要做,那就是在前端应用功能:
forum\resources\views\threads\reply.blade.php

    .
    .
    @can('update',$reply)
        <div class="panel-footer">
            <form method="POST" action="/replies/{{ $reply->id }}">
                {{ csrf_field() }}
                {{ method_field('DELETE') }}

                <button type="submit" class="btn btn-danger btn-xs">Delete</button>
            </form>
        </div>
    @endcan
</div>

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 0
发起讨论 只看当前版本


暂无话题~