Banner Laravel

En este tutorial continuaremos con lo hecho en la primera parte y agregaremos la funcionalidad para crear y eliminar comentarios en los posts.

Para poder continuar con este tutorial es importante que primero revises el post Manejo de roles y habilidades en Eloquent con Bouncer donde aprenderás a instalar y configurar Bouncer, además de haber completado el tutorial Implementar Bouncer en Laravel, parte 1.

Creando el modelo Comment

En el tutorial anterior creamos el modelo Post para almacenar nuestros posts o publicaciones, ahora vamos a crear el modelo Comments que usaremos para nuestros comentarios:

// Ejecuta el siguiente comando en la terminal:
php artisan make:model Comment -mc

Dentro del modelo Comment agregamos lo siguiente:

class Comment extends Model
{
    protected $guarded = [];

    public function post()
    {
        return $this->belongsTo(Post::class);
    }

    public function user()
    {
        return $this->belongsTo(User::class);
    }
}

Editar el modelo de usuario

Nuevamente debemos editar el modelo User, esta vez para agregar el método para relacionar a los usuarios con los comentarios:

class User extends Authenticatable
{
    // ...

    public function comments()
    {
        return $this->hasMany(Comment::class);
    }
}

Controladores

Ahora agregaremos la lógica al controlador CommentController.php:

class CommentController extends Controller
{
    public function store(Post $post, Request $request)
    {
        $comment = $post->comments()->create([
            'user_id' => auth()->id(),
            'body' => $request->get('body')
        ]);

        // Asignamos al autor del comentario la habilidad de poder eliminar su propio comentario
        auth()->user()->allow('delete', $comment);

        return back();
    }

    public function destroy(Comment $comment)
    {
        // Vamos a comprobar que el usuario tiene la habilidad delete sobre este comentario
        $this->authorize('delete', $comment);

        $comment->delete();

        return back();
    }
}

Con auth()->user()->allow('delete', $comment); asignamos la habilidad delete al autor del comentario. Esta habilidad le permitirá a dicho autor eliminar sus propios comentarios.

Rutas

Vamos a editar el archivo web.php y agregar las rutas relacionadas a los comentarios:

// Ruta para crear el comentario:
Route::post('/posts/{post}/comments', 'CommentController@store')->name('comments.store');

// Ruta para eliminar el comentario:
Route::delete('/comments/{comment}', 'CommentController@destroy')->name('comments.destroy');

Vistas

Nos falta sólo una vista, show.blade.php. Vamos a agregar el contenido a este archivo, que debemos crear en conjunto con las otras vistas en resources/views/posts:

@extends('layouts.app')

@section('content')
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <div class="card">
                    <div class="card-header">{{ $post->title }}</div>

                    <div class="card-body">
                        {{ $post->body }}
                    </div>
                </div>

                <h2 class="mt-4 mb-4">Comentarios</h2>

                @foreach ($post->comments as $comment)
                <div class="card mb-2">
                    <div class="card-body">
                        {{ $comment->body }}

                        <hr>

                        @can('delete', $comment)
                            <form action="{{ route('comments.destroy', $comment) }}" method="POST">
                                @csrf
                                @method('delete')
                                <button class="btn btn-danger btn-sm float-right">Eliminar comentario</button>
                            </form>
                        @endcan

                        Publicado por <strong>{{ $comment->user->name }}</strong>
                    </div>
                </div>
                @endforeach

                @auth
                <h2 class="mt-4 mb-4">Agregar nuevo comentario</h2>
                    <form action="{{ route('comments.store', $post) }}" method="POST">
                        @csrf
                        <div class="form-group">
                            <textarea name="body" rows="5" class="form-control" required></textarea>
                        </div>
                        <div class="form-group">
                            <button type="submit" class="btn btn-primary">Publicar</button>
                        </div>
                    </form>
                @endauth
            </div>
        </div>
    </div>
@endsection

Con @can('delete', $comment) comprobamos si el usuario tiene la habilidad para eliminar el comentario siendo iterado y de ser así mostramos el botón para eliminar. En el método destroy del controlador CommentController también realizamos la misma comprobación utilizando authorize para asegurar la acción.

Recuerda que el usuario puede manipular el HTML y por lo tanto siempre debes proteger las rutas o controladores.

Si has seguido todos los pasos correctamente ya deberías tener implementado Bouncer en Laravel:

Ejemplo creado con Bouncer y Laravel

Si tienes alguna pregunta o inquietud no dudes en dejarla en los comentarios.

Puedes ver y descargar el código de este ejemplo en GitHub: laravel-bouncer-example.

Si te ha gustado este tutorial y te interesa el tema de manejo de roles y habilidades puedes ver una explicación detallada y a fondo en el curso Técnicas de Autorización con Laravel donde aprenderás no sólo a utilizar Bouncer sino también sobre muchos otros temas respecto al manejo de roles, permisos y autorización:

No olvides seguirnos en Twitter y suscribirte a nuestro boletín:

Suscríbete a nuestro boletín

Te enviaremos publicaciones con consejos útiles y múltiples recursos para que sigas aprendiendo.

Regístrate hoy en Styde y obtén acceso a todo nuestro contenido.