DBIx::Class::Relationship
Las clases ejemplo
Como no me termino de fiar de mi memoria, voy a emplear en estas notas clases más o menos reales que existen en alguna de mis aplicaciones, sin entrar en detalle en sus atributos concretos, pero contando las posibles relaciones entre ellas:
Lugares: registro de zonas geográficas del mundo mundial.
Etiquetas: Textos con los que marcar a otros objetos, de libre contenido tales como cliente, ventas, moroso, obsoleta, ...
Direcciones: registro de direcciones postales que incluyen el nombre del remitente y el texto literal de su dirección para el servicio postal local.
- Puede pertenecer a un lugar geográfico normalizado.
RazonSocial: datos fiscales de las personas físicas ó jurídicas.
PersonasyEtiquetas: relación de etiquetas sobre una persona.
Personas: registro de personas físicas y/ó jurídicas con la información justa sobre ellas.
- Debe tener una zona de ventas que coincide con una zona geográfica.
- Puede tener varias direcciones postales.
- Puede tener una ó varias etiquetas clasificatorias.
- Debe tener una razón social.
El método de clase add_relationship
Este método de clases es el que crea una relación entre dos clases y el que emplean finalmente los métodos descritos más abajo para hacer su trabajo.
Personas->add_relationship( 'zona_de_ventas', 'Lugares', 'zona');
Llamaremos lado izquierdo a la tabla donde se declara la relación,
representada por Personas
, y lado derecho a la tabla con la que se
establece la relación, representada por Lugares
.
Los parámetros deben ser:
Nombre de la relación entre las dos clases empleada para añadir un método a la clase del lado izquierdo.
Clase referenciada que necesita estar cargada antes de llamar a este método.
Condiciones de unión, que debe ser una representación de la unión entre las clases al estilo de SQL::Abstract.
Se pueden usar dos pseudo tablas:
- self: hace referencia a la tabla del lado izquierdo.
- foreign: hace referencia a la tabla del lado derecho de la relación.
Es decir, que si estamos creando una relación entre una persona (clase Personas) y su zona de ventas (clase Lugares), en el que la primera apunta a la segunda, podremos expresarla como sigue:
{ self.zona_de_ventas => foreign.id }
Esto también puede aplicarse a las claves referenciales multicolumna.
Referencia a un hash con los siguientes atributos:
join_type: tipo de unión a emplear en la relación, siendo válido cualquier tipo SQL (como por ejemplo
LEFT
óRIGHT
) que será situado en la órden SQL inmediatamente antes de la claúsula JOIN.proxy: referencia a una lista de nombres de métodos de acceso en la clase externa (lado derecho) que serán creados en la clase principal (lado izquierdo) si existen en la primera.
accessor: Determina el tipo de método de acceso a crear para la relación.
single
: para cuando existe una relación uno a uno.multi
: para cuando la relación es de tipo uno a muchos, y en este caso se crea también un método prefijado conadd_to_
, que llamará al métodocreate_related()
en DBIx::Class::Relationship::Base.filter
: para cuando la relación es también de tipo uno a uno, pero queremos que el método de acceso se comporte también como un método de acceso a columna.
cascade_delete: Determina qué hacer cuando se borra el objeto al que apunta una relación. Si es verdadero (1) se efectúa un borrado sobre todos los objetos relacionados y si es falso (0) el borrado se limita al objeto en sí.
cascade_update: Similar al anterior, se aplica en este caso a las modificaciones de la clave primaria. Si es verdadero se actualizan los objetos referenciantes para que apunten al nuevo identificador y si es falso se quedan como están.
Relación uno a uno (belongs_to)
Personas->belongs_to( 'zona_de_ventas', 'Lugares', 'zona' );
Interpretable como esta tabla referencia a otra ó existe una relación uno a uno entre las dos, y empleada cuando una tabla contiene una ó varias columnas con la clave primaria de otra, es decir, que la referencia.
También se caracteriza por permitir el uso de claves primarias multicolumna entre las tablas.
Los parámetros para crear la relación son los siguientes:
- Nombre del método de acceso que se crea en la tabla referenciante
(
Personas
) para acceder a la tabla referenciada (Lugares
). - Nombre de la clase referenciada, que debe tener una clave primaria.
- Forma de relación entre las tablas:
- Nombre de una columna que debe estar presente en las dos, formando la clave primaria en la tabla referenciada.
- Referencia a un hash equiparando las columnas de una y otra tabla para el caso de que la clave primaria sea multicolumna.
- Representación de la unión entre tablas al estilo de SQL::Abstract.
- Atributos de la unión (opcional).
Los atributos predeterminados de la relación son:
- accessor: filter ó single.
- join_type: sin determinar
- cascade_delete: sin determinar aunque presumiblemente sea falso
- cascade_update: sin determinar aunque presumiblemente sea falso
Existen dos métodos más que crean relaciones uno a uno entre dos tablas, con la particularidad de que la clave primaria referenciada debe estar formada por una única columna.
Relación tiene sólo uno (has_one)
Personas->has_one( 'razon_social', 'RazonSocial', 'idfiscal' );
Crea una relación uno a uno entre las dos clases con la implicación de que dicha relación exista siempre. Emplea una combinación interna (inner join) para ello, y debería utilizarse cuando una fila en una tabla tiene exactamente una fila relacionada en la otra.
Los atributos predeterminados de la relación son:
- accessor: single
- join_type: undef
- cascade_delete: 1
- cascade_copy: 1
Relación puede que tenga una (might_have)
Direcciones->might_have( 'zona', 'Lugares' );
Crea una relación uno a uno opcional entre dos clases, es decir, similar a
la anterior excepto que la combinación empleada es de combinación interna
izquierda, lo que quiere decir que el resultado de una consulta sobre las dos
clases retornará como nulos los datos de la clase Lugares
para aquellos
registros de la clase Direcciones
sin correspondencia.
Los atributos predeterminados de la relación son:
- accessor: single
- join_type: LEFT
- cascade_delete: 1
- cascade_copy: 1
Relación uno a muchos (has_many)
Personas->has_many( 'direcciones', 'Direcciones' );
Crea una relación uno a muchos entre dos clases, que consiste en que una ó
más filas de la clase externa contendrán la clave primaria de la clase
referenciada, en una ó varias columnas. Por defecto intentará utilizar el
nombre del método de acceso ($accessor_name
) como clave externa en la tabla
referenciante.
Tras esta llamada se crean varios métodos en la clase referenciada:
direcciones
: Nombre con el que se consigue un objeto ResulSet para tener acceso a los datos de la clase referenciante.direcciones_rs
: Un sinónimo del anterior con la particularidad de retornar siempre un objeto sin importar en qué contexto ha sido llamado.add_to_direcciones
: Método para añadir objetos en la tabla referenciante desde la clase referenciada.
Los atributos predeterminados de la relación son:
- accessor: multi
- join_type: LEFT
- cascade_delete: 1
- cascade_copy: 1