Los datos de las ofertas de trabajo, afiliados y categorías se guardan en una base de datos relacional. Por otra parte, como Symfony es un framework orientado a objetos, nuestro objetivo es trabajar con objetos siempre que sea posible. Así por ejemplo, preferimos utilizar objetos a tener que escribir sentencias SQL para obtener los registros de la base de datos.
Para trabajar con objetos en una base de datos relacional, es necesario realizar un mapeo o conversión entre la información de la base de datos y los objetos PHP. Este mapeo se realiza con unas herramientas llamadas ORM y Symfony incluye por defecto dos de las más utilizadas: Propel y Doctrine. En este tutorial vamos a utilizar Propel.
A partir de la descripción de cada tabla y de las relaciones entre tablas, el ORM crea las clases PHP necesarias para trabajar con objetos. Existen dos formas de crear la descripción del esquema de datos: mediante la introspección de una base de datos existente o creando el esquema manualmente.
Nota Existen aplicaciones para crear bases de datos gráficamente (por ejemplo Dbdesigner de Fabforce) y para generar archivos de tipo schema.xml
(por ejemplo DB Designer 4 TO Propel Schema Converter).
Como todavía no tenemos ninguna base de datos y como queremos que Jobeet funcione con todos los tipos de gestores de bases de datos, vamos a crear el archivo del esquema a mano. Para ello, abre el archivo config/schema.yml
y añade lo siguiente tal y como está escrito:
# config/schema.yml
propel:
jobeet_category:
id: ~
name: { type: varchar(255), required: true, index: unique }
jobeet_job:
id: ~
category_id: { type: integer, foreignTable: jobeet_category, foreignReference: id, required: true }
type: { type: varchar(255) }
company: { type: varchar(255), required: true }
logo: { type: varchar(255) }
url: { type: varchar(255) }
position: { type: varchar(255), required: true }
location: { type: varchar(255), required: true }
description: { type: longvarchar, required: true }
how_to_apply: { type: longvarchar, required: true }
token: { type: varchar(255), required: true, index: unique }
is_public: { type: boolean, required: true, default: 1 }
is_activated: { type: boolean, required: true, default: 0 }
email: { type: varchar(255), required: true }
expires_at: { type: timestamp, required: true }
created_at: ~
updated_at: ~
jobeet_affiliate:
id: ~
url: { type: varchar(255), required: true }
email: { type: varchar(255), required: true, index: unique }
token: { type: varchar(255), required: true }
is_active: { type: boolean, required: true, default: 0 }
created_at: ~
jobeet_category_affiliate:
category_id: { type: integer, foreignTable: jobeet_category, foreignReference: id, required: true, primaryKey: true, onDelete: cascade }
affiliate_id: { type: integer, foreignTable: jobeet_affiliate, foreignReference: id, required: true, primaryKey: true, onDelete: cascade }
Nota Si eres de los que prefieres crear la base de datos directamente con sentencias SQL, puedes generar el archivo de configuración schema.yml
a partir de una base de datos existente mediante la tarea propel:build-schema
$ php symfony propel:build-schema
La tarea anterior requiere que se haya configurado una base de datos en el archivo databases.yml
, tal y como se explica más adelante. Por tanto, si ejecutas ahora esa tarea, no va a funcionar correctamente porque no sabe la base de datos para la que debe crear el esquema.
El esquema de datos no es más que la traducción del diagrama de entidad-relación al formato YAML.
El archivo schema.yml
describe todas las tablas y columnas de la base de datos. Cada columna se describe con la siguiente información:
type
: el tipo de columna, que puede serboolean
,tinyint
,smallint
,integer
,bigint
,double
,float
,real
,decimal
,char
,varchar(size)
,longvarchar
,date
,time
,timestamp
,blob
yclob
.required
: si valetrue
, la columna es obligatoria.index
: si valetrue
, se crea un índice para la columna; si valeunique
, se crea un índice único.primaryKey
: indica que esta columna es clave primaria de la tabla.foreignTable
,foreignReference
: indica que esta columna es clave externa de otra tabla.
En las columnas cuyo valor es simplemente ~
, que en realidad es como se indica el valor null
en YAML (id
, created_at
y updated_at
), Symfony adivina cuál es la mejor configuración para esa columna (los campos llamados id
se consideran claves primarias y los campos llamados created_at
y updated_at
se consideran de tipo timestamp
).
Nota El atributo onDelete
define el comportamiento de las claves primarias ante las sentencias ON DELETE
. Propel admite los valores CASCADE
, SETNULL
y RESTRICT
. Cuando se borra por ejemplo el registro de una oferta de trabajo job) todos los registros relacionados de la tabla jobeet_category_affiliate
se borran automáticamente mediante la base de datos o mediante Propel si el sistema gestor de base de datos no es capaz de hacerlo.