Laravel y Base de Datos

Entorno de trabajo y repaso de Laravel

1

Qué aprenderás sobre Laravel Avanzado

2

Repaso de Laravel y requisitos del curso

3

Configuración de la base de datos-SQLite en Laravel

4

Instalación, configuración y uso de Homestead

5

Instalar Laravel Sanctum

6

API de autenticación: laravel UI y laravel sanctum

Manejo de tu base de datos con Laravel

7

Capa de transformación con API Resources

8

Manejo de relaciones en bases de datos con Laravel

9

Relaciones Polimórficas en Eloquent

La terminal de Laravel

10

Cómo crear comandos para la terminal de Laravel

11

Ejecutando comandos desde la API

12

Programación de tareas

Eventos y tareas de Laravel

13

Eventos y Listeners en Laravel

14

Eventos de Eloquent

15

Introducción al uso de Queues y Jobs

16

Cómo disparar eventos en Queues

17

Laravel Horizon

Manejo de errores

18

Cómo capturar y leer errores con la clase Handler

19

Excepciones personalizadas

20

Excepciones HTTP personalizadas y debugging con Laravel Telescope

21

Configuración de logs y channels en Laravel

El corazón de Laravel

22

Ciclo de vida de una aplicación en Laravel

23

¿Qué son los service containers?

24

¿Cómo funciona un service container?

25

Registro y carga de clases con service providers

Creación de paquetes

26

¿Cómo crear mis propios paquetes de Laravel?

27

Propiedades para manejo de dependencias

28

Comprende el archivo composer.json

29

Extendiendo composer.json, autocarga de clases y PSR-4

30

Crear mis propios Services Providers

31

Publicación de archivos

32

Uso de repositorios locales

33

Publicación de paquetes en packagist

No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Eventos y Listeners en Laravel

13/33
Recursos

Aportes 14

Preguntas 2

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Otra forma de generar eventos y listeners directamente es escribiendolos en el EventServiceProvider con su namespace completo dentro del array de eventos y Laravel tiene un comando especial para generar ambos directamente lo cual puede ser un poco mas productivo en terminos de crear codigo mas rapido el comando es:

php artisan event:generate

que mal curso, no explica nada, el código ya lo tiene hecho no lo va construyendo.

Events: ACCIONES que ocurren por usuarios. Ejemplo: USUARIO se REGISTRA.

Listeners: DISPARADORES a través de los EVENTOS. Ejemplo: ENVIAR mail debido a una REGISTRACIÓN.

Comparto mi solución al reto:
Primera parte - Prueba de Unrate
Siguiendo TDD primero creamos una prueba para testear que un usuario en efecto pueda quitar su calificación de un producto:

public function test_unrating_model()
    {
        $this->withoutExceptionHandling();
        $user = User::factory()->create();
        $product = Product::factory()->create();

        $user->rate( $product, 5 );

        $user->unrate( $product );

        $rating = Rating::first();

        $this->assertEmpty( $rating );
    }

Creamos un usuario y un producto, le damos un calificación y luego la borramos, comprobamos que ya no exista más esa calificación, les dejo el commit en mi repositorio: test_unrating_model
.
Segunda parte - método unrate del Trait CanRate
Como los usuarios tiene el trait CanRate, hace sentido que definamos el método para borrar calificación dentro de esa clase:

public function unrate( Model $model )
    {
        // $rating = \App\Models\Rating::query()
        //                             ->where( 'qualifier_id', $this->id )
        //                             ->where( 'rateable_id', $model->id )
        //                             ->first();

        // $rating->delete();

        $this->ratings( $model->getMorphClass() )->detach( $model->getKey() );

        event( new ModelUnrated( $this, $model ) );

        return true;
    }

llegué a una solución diferente a la que el profe, pero me pareció más elegante la de él por lo que la usé también, cabe aclarar que en este método dispararemos el evento del reto. Dejo el commit de mi repositorio: método unrate
.
Tercera parte - creación del evento
Pues creamos el evento que guardara y expondrá el nombre del qualifier (quien quitó su calificación) y el nombre del rateable (producto al cual se le quitó calificación):

<?php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class ModelUnrated
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $qualifier;
    public $rateable;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct( Model $qualifier, Model $rateable )
    {
        $this->qualifier = $qualifier;
        $this->rateable = $rateable;
    }

    public function getQualifier(): Model
    {
        return $this->qualifier;
    }

    public function getRateable(): Model
    {
        return $this->rateable;
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
        return new PrivateChannel('channel-name');
    }
}

.
Cuarta parte - Creación del Listener
Vamos a crear el Listener que se encargara de atender el evento cuando este se dispare, para enviar una notificación por email que informe el nombre de quien quitó su calificación y a que producto:

<?php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class ModelUnrated
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $qualifier;
    public $rateable;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct( Model $qualifier, Model $rateable )
    {
        $this->qualifier = $qualifier;
        $this->rateable = $rateable;
    }

    public function getQualifier(): Model
    {
        return $this->qualifier;
    }

    public function getRateable(): Model
    {
        return $this->rateable;
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
        return new PrivateChannel('channel-name');
    }
}

les dejo el commit en mi repositorio: creación de listener

.
Quinta parte - Creación de la notificación
creamos una notificación donde el constructor guarda los valores anteriormente mencionados en variable privadas y redactamos el contenido del correo:

<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;

class ModelUnratedNotification extends Notification
{
    use Queueable;

    private $qualifierName;
    private $rateableName;

    /**
     * Create a new notification instance.
     *
     * @return void
     */
    public function __construct( string $qualifierName, string $rateableName )
    {
        $this->qualifierName = $qualifierName;
        $this->rateableName = $rateableName;
    }

    /**
     * Get the notification's delivery channels.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        return ['mail'];
    }

    /**
     * Get the mail representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return \Illuminate\Notifications\Messages\MailMessage
     */
    public function toMail($notifiable)
    {
        return (new MailMessage)
                    ->line( "El usuario {$this->qualifierName} ha removido su calificación de tu producto {$this->rateableName}" );
    }

    /**
     * Get the array representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function toArray($notifiable)
    {
        return [
            //
        ];
    }
}

Les dejo el commit de mi repositorio: notificación
.
Sexta parte - Declaramos el evento y el listener en Laravel

ModelUnrated::class => [
            SendEmailModelUnratedNotification::class
        ]
        ]

y estamos listos para seguir!

aca al profe si le falto explicar como probar ese event y listener, sera investigar. platzi no esta poniendo atencion a la calidad de los cursos

Creo que en esta clase no hemos seguido una convención de nombres.

Interesante, se pueden manejar eventos con Laravel, eso si no lo sabía 🤔

Dejo el enlace con el commit de esta clase en Laravel 8

https://github.com/RetaxMaster/platzi-api/commit/dbcb7a5a28b57778cff8aaa2757c97ce59f1a4ee

![](https://static.platzi.com/media/user_upload/mailtrap-b2e4ce64-63ce-4c45-aafe-ee7dd8c8a2bf.jpg)

En php 8.2 podemos escribir el constructor de una forma mucho mejor

public function __construct(
        public readonly Model $qualifier,
        public readonly Model $rateable,
        public readonly float $score,
    )
    {
        //
    }

De esa forma no es necesario usar getters o setter

Cual es el git del proyecto

Eventos todas la acciones que user inicia

reto
php artisan make:event ModelUnrated
Utils/CanRate //disparar evento en el method unrate
php artisan make:listener SendEmailModelUnratedNotification
php artisan make:notification ModelUnratedNotification
agregamos nuestro evento al event provider

Estoy haciendo un proyecto en Laravel y tengo la siguiente estructura de tablas

Product
id
name
image
code
Price
id
product_id
purchase_price
sale_price

Warehouse
id
name
user_id
address

product_warehouse
product_id
warehouse_id
product_quantity
price_id

La ultima tabla la utilizo como tabla pivote y me permite obtener los productos que tiene un almacén, como se puede ver es una tabla pivote, pero me gustaría obtener el precio del producto utilizando el price_id de dicha tabla pivote. No se si alguien me podría asesorar me ayudaría mucho, intente usar el HasOneTrought desde el producto hacia el precio con el warehouse pero no me funciono, o si alguien tendría una mejor idea para resolver esto
’’‘
public function price(){
return $this->hasOneThrough(Price::class,Warehouse::class,‘product_id’,‘price_id’);
}
’’'
Saludos

Asi podemos **probar rapidamente**, usando la interfaz web, en este caso el log reporta que el evento se disparo: ![](https://static.platzi.com/media/user_upload/prueba%20rapida-44f1db9a-5dcf-40b1-87cd-098ddfa9a10e.jpg) En el constructor del evento **ModelRated** reporto hacia el log: `public function __construct(Model $qualifier, Model $rateable, float $score)    ` `{        ` `$this->qualifier = $qualifier;        ` `$this->rateable = $rateable;        ` `$this->score = $score;` `Log::info('ModelRated event fired.', ['qualifier' => $qualifier, 'rateable' => $rateable, 'score' => $score]);` `}`