41. Relación uno a uno polimorfica

En una relación uno a uno polimórfica en una base de datos, una fila en una tabla se relaciona con una sola fila en una tabla de otra entidad, pero en lugar de especificar una tabla de destino específica, la relación puede apuntar a varias tablas diferentes. Esto se logra mediante el uso de claves foráneas que apuntan a una tabla de identificadores y una tabla de tipos.

Un ejemplo común de una relación uno a uno polimórfica es un sistema de comentarios, donde un comentario puede estar relacionado con una publicación o con una imagen, pero no puede estar relacionado con ambos al mismo tiempo. En este caso, se crea una tabla de comentarios que contiene una clave foránea a una tabla de identificadores y una tabla de tipos que puede ser una tabla de publicaciones o una tabla de imágenes. De esta manera, se puede establecer una relación uno a uno polimórfica entre las tablas de comentarios, publicaciones e imágenes. La relación uno a uno polimórfica es útil para simplificar la estructura de la base de datos y evitar la duplicación de tablas en casos donde las relaciones son similares pero no idénticas.


1 comentarios

Inicia sesión para comentar

Comentarios:

  • Walter

    Walter hace 1 año

    ? Relaciones uno a uno polimórficas

             Evitamos reservar espacio para campos opcionales.

             Encontramos, por ejemplo, el campo image para las tablas users y posts.

             Creamos entonces una tabla images que contendrá los campos imageable_id e imageable_type que contendrán el id y el modelo respectivamente de la tabla relacionada. Estos dos campos forman la llave primaria compuesta de la tabla images ya que tenemos una relación uno a uno.

     

    ? Creamos el modelo Image con su migración

     

        php artisan make:model Image -m

     

    ? Completamos los campos en el método up del archivo de migración

     

        $table->string('url');
        $table->unsignedBigInteger('imageable_id');
        $table->string('imageable_type');
        
        $table->primary(['imageable_id', 'imageable_type']);

     

            Ya hemos generado la relación uno a uno polimórfica a nivel de BD. Luego,

     

        php artisan migrate

     

    ? Configurando la relación uno a uno polimórfica a nivel de modelos

     

            Comenzando con el modelo Image le agregamos el siguiente método:

     

        public function imageable() {
        	return $this->morphTo();
        }

     

            De esta manera indicamos que vamos a usar esta tabla para realizar una relación polimórfica.

            Continuamos con los modelos Post y User agregándoles:

     

        public function image() {
        	return $this->morphOne('App\Models\Image', 'imageable');
        }

     

    ? Probando la relación en nuestros modelos

            Habilitamos la carga masiva en el modelo Image:

     

        protected $guarded = [];

     

            Abrimos Tinker:

     

        php artisan tinker
        >>> use App\Models\Image;
        >>> Image::create([
        		'url' => 'url 1', 
        		'imageable_id' => 1, 
        		'imageable_type' => 'App\Models\User'
        	]);
        >>> use App\Models\User;
        >>> $user = User::find(1);
        >>> $user->image;
        >>> $user->image();

     

            Si en lugar de acceder a la propiedad image lo hacemos al método image() vemos que nos devuelve el tipo de relación que existe entre users e images y podemos usar esa relación para ingresar registros en la tabla images.

     

    ? Los métodos attach, detach y sync son exclusivos para relaciones muchos a muchos. Para los demás tipos de relaciones podemos usar el método create.

     

        >>> $user->image()->create(['url' => 'url 1']);