Contenido del curso

Botón de corazón reactivo con Livewire

Resumen

Agregar un botón de corazón parece trivial, pero transforma la experiencia del usuario en cualquier plataforma de preguntas y respuestas. Aquí aprendes a construir esta funcionalidad reactiva usando Livewire en Laravel, aplicándola a preguntas, respuestas y comentarios desde un solo componente reutilizable.

Por qué crear un componente Livewire para los likes

La reactividad es el corazón de esta implementación. En lugar de recargar la página cada vez que alguien presiona el botón, Livewire permite que la acción se actualice al instante.

El primer paso es generar el componente con el comando php artisan make:livewire corazon [01:00]. Esto crea dos archivos: la clase PHP que maneja la lógica y la vista Blade que define el diseño.

¿Qué es un componente Livewire? Es una pieza reutilizable que combina lógica PHP y vista Blade, capaz de actualizar el DOM sin recargar la página ni escribir JavaScript adicional.

Cómo integrar el componente en preguntas, respuestas y comentarios

Una vez creado, el componente se inserta donde aparezca un corazón. La sintaxis es la misma en los tres contextos, solo cambia la entidad que se pasa como parámetro:

  • En preguntas: <livewire:corazon :model="$pregunta" />.
  • En respuestas: <livewire:corazon :model="$respuesta" />.
  • En comentarios: <livewire:corazon :model="$comentario" />.

Esta flexibilidad es posible porque la propiedad $model acepta cualquier modelo de Eloquent. Tú decides qué entidad recibe el corazón.

Cómo funciona el método Toggle para activar o quitar el like

El diseño del componente usa una condición simple: si la entidad ya recibió un corazón, se pinta de rojo; si no, queda gris [04:30]. Al hacer clic se dispara el método toggle(), que decide si crear o eliminar el registro.

La lógica dentro de la clase PHP queda así:

php public Model $model;

public function toggle() { if ($this->model->hasHearted()) { $this->model->unheart(); } else { $this->model->heart(); } }

La propiedad $model está tipada con la clase Model de Eloquent, lo que garantiza que siempre reciba una instancia válida sin importar si es pregunta, respuesta o comentario.

Qué es una relación morphMany y por qué usarla aquí

Un corazón puede pertenecer a tres entidades distintas, así que la solución elegante es una relación polimórfica. En cada modelo se define:

php public function hearts() { return $this->morphMany(Heart::class, 'heartable'); }

Con morphMany evitas crear una tabla de likes por cada tipo de contenido. Una sola tabla guarda todos los corazones y la relación identifica a qué entidad pertenece cada uno.

¿Qué es morphMany en Laravel? Es una relación polimórfica que permite a un modelo tener muchos registros relacionados de un tipo común, vinculados a múltiples modelos diferentes mediante un campo *_type y un *_id.

Cómo verificar y registrar los likes en la base de datos

Para saber si un usuario ya dio corazón se consulta la relación con un where. En el ejemplo de la clase se trabajó con el usuario fijo número 20 [07:15], pero después esto se conecta al usuario autenticado.

El método para asignar el corazón crea un registro nuevo:

php public function heart() { $this->hearts()->create(['user_id' => 20]); }

Al ejecutar esto por primera vez, Laravel lanza un error de mass assignment. Esa es una capa de seguridad: el modelo Heart no permite guardar el campo user_id hasta que lo agregues al arreglo $fillable. Lo añades y el registro se crea sin problema.

Cómo eliminar el like cuando el usuario lo retira

El método inverso busca el registro existente y lo elimina:

php public function unheart() { $this->hearts()->where('user_id', 20)->delete(); }

Esta lógica se replica en los tres modelos: pregunta, respuesta y comentario. Funciona, pero deja una pista evidente: hay código repetido. Y ahí está la oportunidad de mejora.

Qué archivos cambian al implementar esta funcionalidad

Al correr git status aparecen los archivos modificados [11:20]:

  • Los modelos Question, Answer y Comment con los métodos hearts(), heart(), unheart() y hasHearted().
  • Las vistas show.blade.php donde se incrustó el componente Livewire.
  • El nuevo componente Corazon, tanto en su clase PHP como en su vista Blade.

Después de recargar la página, el estado del corazón se mantiene porque la consulta se hace contra la base de datos en cada renderizado. Eso confirma que la persistencia funciona.

La próxima iteración será refactorizar esta lógica con un trait para evitar copiar y pegar los mismos métodos en cada modelo. ¿Cómo resolverías tú la duplicación de código en este caso? Cuéntalo en los comentarios.