A la hora de desarrollar una aplicación debemos de tener claro las acciones que va a realizar la misma y mediante que URL's vamos a invocarlas. Ejemplo de URL's que podremos hacer en nuestra aplicación.
URL Action
-------------------------------------------------------------
/ Listar tareas (página principal)
/insertar Insertar una tarea
/eliminar/x Eliminar la tarea x
/editar/x Editar la tarea x
Creación de la página principal
Configurar la base de datos
Antes de comenzar realmente, tendrás que configurar tu información de conexión a la base de datos. Por convención, esta información se suele configurar en el archivo app/config/parameters.yml aunque también puedes cambiarla desde el navegador entrando en http://localhost/.../web/app_dev.php (esta es la ruta completa si no has configurado el host virtual para el DocumentRoot) y entrando en el apartado configure.
El resultado es un fichero similar a este:
parameters:
database_driver: pdo_mysql
database_host: 127.0.0.1
database_port: null
database_name: tareas
database_user: root
database_password: tu_password
mailer_transport: smtp
mailer_host: 127.0.0.1
mailer_user: null
mailer_password: null
locale: en
secret: e6ea6da2ce387ebafd55fe3296eeb3a4
database_path: null
Ahora podemos crear la base de datos vacía, sin tablas, con la herramienta app/console de Symfony2:
php app/console doctrine:database:create
Y podemos comprobar su creación, por ejemplo con phpMyAdmin.
Implementación del modelo y entidades
Como comentamos en el anterior tutorial, el código del modelo de la aplicación lo vamos a introducir en el directorio /src/Entity/.
La página inicial esta compuesta por un listado de tareas almacenadas previamente en la base datos. Por lo tanto llega el momento de introducir el concepto de ORM. Ya que Simfony 2 utiliza la librería ORM Doctrine 2. Según la wikipedia: La asignación objeto-relacional (más conocida por su nombre en inglés, Object-Relational mapping, o sus siglas ORM, O/RM, y O/R mapping) es una técnica de programación para convertir datos entre sistemas de tipos incompatibles utilizando lenguajes de programación orientados a objetos”. Esto crea, en efecto, una “base de datos de objetos virtual” que se puede utilizar dentro del lenguaje de programación. En la que las habilidades del ORM traducen desde datos de una base de datos relacional como MySQL en objetos PHP que podemos manipular. Esto nos permite encapsular la funcionalidad que necesitamos en una tabla dentro de una clase.
Por lo tanto es correcto pensar en que cada una de las tablas que crearemos, será encapsulada dentro de una clase. Y cada una de esas clases serán consideradas entidades. En pocas palabras podríamos decir que el objetivo de una entidad es el de contener datos.
Para empezar a trabajar con Doctrine, tenemos que informar a Doctrine 2 cómo debe asignar la entidad (Tarea) a la base de datos. Tal información se especifica en forma de metadatos utilizando las asignaciones de Doctrine 2. Puedes especificar los metadatos en una serie de formatos, incluyendo YAML, PHP, XML y Anotaciones. En esta ocasión usaremos anotaciones. Es importante señalar que no es necesario persistir todas las propiedades de la entidad, por lo tanto no deberás proporcionar metadatos para estas. Esto nos da la flexibilidad de elegir sólo las propiedades que necesitamos que Doctrine 2 asigne a la base de datos. Ya que puede ser útil tener propiedades que utilizaremos como auxiliares para interactuar con los otros elementos, pero que no necesitamos guardar.
Antes de presentar nuestra entidad vamos a ver unos conceptos de las anotaciones. Mediante estas anotaciones los atributos de nuestra entidad se van a convertir en columnas de nuestra tabla en la base de datos:
- Primero de todo debemos que declarar y asociar la entidad con la tabla que se creará.
/**
* @ORM\Entity
* @ORM\Table(name="tarea")
*/
class Tarea {
}
- Declararemos el identificador de la tabla asociada, definiendo que dicha columna contendrá datos de tipo entero y los valores serán auto-incrementados.
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
- Especificaremos el resto de columnas de la tabla asociada, con el nombre, tipo y atributos opcionales dependiendo del tipo de columna definida.
/**
* @ORM\Column(type="string", length=100, nullable=false)
*/
protected $descripcion;
/**
* @ORM\Column(type="boolean", nullable=false)
*/
protected $estado;
/**
* @ORM\Column(type="string",columnDefinition="ENUM('baja', 'media','alta')", nullable=false)
*/
protected $prioridad;
Para obtener más información sobre los tipos de datos disponibles y sus atributos consultar aquí.
En posteriores tutoriales y ejemplo, veremos como relacionar claves ajenas de diferentes tablas.
1. Entidad Tarea
/*src/Tarea/ListadoBundle/Entity/Tarea.php*/
<?php
namespace Tarea\ListadoBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="tarea")
*/
class Tarea {
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(type="string", length=100, nullable=false)
*/
protected $descripcion;
/**
* @ORM\Column(type="date")
*/
protected $fechaRealizar;
/**
* @ORM\Column(type="boolean", nullable=false)
*/
protected $estado;
/**
* @ORM\Column(type="string",columnDefinition="ENUM('baja', 'media','alta')", nullable=false)
*/
protected $prioridad;
Importante: para que Doctrine reconozca el tipo enum hay que indicárselo en app/config/config.yml
doctrine:
dbal:
//...
mapping_types:
enum: string
Una utilidad muy útil, sobretodo si es una entidad con numerosas propiedades, es la de poder generar todos los métodos de acceso a las propiedades de las entidades automáticamente. Esto se consigue mediante el siguiente comando.
$ php app/console doctrine:generate:entities Tarea
Observemos como ahora la clase/entidad Tarea se ha rellenado con los 'getters' y 'setters' de las distintas propiedades. Muy útil.
Nota: Cada vez que hagas algún cambio en los metadatos ORM de la entidad o añadas nuevos atributos, puedes ejecutar esta orden para generar cualquier captador adicional. Esta orden no hará modificaciones a los métodos de acceso existentes en la entidad, por lo tanto tus métodos de acceso existentes nunca se van a remplazar con esta orden. Esto es importante ya que más tarde puedes personalizar algunos de los métodos de acceso predeterminados.
Ahora ya estamos en disposición de generar la tabla en la base de datos. Y para ello utilizaremos el siguiente comando:
$ php app/console doctrine:schema:create
O para actualizar la tabla ya creada si se han modificado la entidad:
$ php app/console doctrine:schema:update --force
Esto ejecutará el código SQL necesario para generar el esquema de base de datos para la entidad Tarea. Además le puedes pasar la opción --dump-sql de la tarea para volcar el SQL en lugar de ejecutarlo contra la base de datos. Si ves tu base de datos, notarás que la tabla tarea se ha creado, con los campos que configuraste en la información de asignación. Muy útil también.
2. Fixtures
Antes de pasar al controlador, vamos a ver como introducir datos de prueba mediante el paquete Fixtures de Doctrine. Como no está entre los componentes básicos preinstalados de la edición estandar de Symfony 2.2, vamos a instalarlo mediante Composer.
Para ello iremos al fichero composer.json de la raíz de nuestro proyecto, y en la clave 'require' añadiremos lo siguiente (recuerda que menos el último, cada subelemento de 'require' va separado por una coma).
"doctrine/doctrine-fixtures-bundle": "dev-master"
Y finalmente actualizaremos las dependencias (recuerda que composer utiliza git).
$ composer update
Si todo ha ido bien, a parte de que composer no habrá dado error, en el directorio vendor/doctrine/doctrine-fixtures-bundle estará FixturesBundle y solo nos faltará registrar el paquete descargado en app/appKernel.php
public function registerBundles()
{
$bundles = array(
// ...
new Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle(),
// ...
);
// ...
}
Implementemos una clase con datos de prueba para Tarea. Esta clase la implementaremos dentro de DataFixtures/ORM del Bundle.
//src/Tarea/ListadoBundle/DataFixtures/ORM/TareaFixtures.php
<?php
namespace Tarea\ListadoBundle\DataFixtures\ORM;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\DataFixtures\FixtureInterface;
use Tarea\ListadoBundle\Entity\Tarea;
class TareaFixtures implements FixtureInterface
{
public function load(ObjectManager $manager)
{
$Tarea1 = new Tarea();
$Tarea1->setDescripcion('Pasear al Yorkie');
$Tarea1->setFechaRealizar(new \DateTime('2013-5-1'));
$Tarea1->setEstado(false);
$Tarea1->setPrioridad('alta');
$manager->persist($Tarea1);
$Tarea2 = new Tarea();
$Tarea2->setDescripcion('Comprar Pan');
$Tarea2->setFechaRealizar(new \DateTime('2013-5-2'));
$Tarea2->setEstado(false);
$Tarea2->setPrioridad('media');
$manager->persist($Tarea2);
$Tarea3 = new Tarea();
$Tarea3->setDescripcion('Hacer footing');
$Tarea3->setFechaRealizar(new \DateTime('2013-5-2'));
$Tarea3->setEstado(true);
$Tarea3->setPrioridad('baja');
$manager->persist($Tarea3);
$Tarea4 = new Tarea();
$Tarea4->setDescripcion('ir al veterinario');
$Tarea4->setFechaRealizar(new \DateTime('2013-5-2'));
$Tarea4->setEstado(false);
$Tarea4->setPrioridad('alta');
$manager->persist($Tarea4);
$manager->flush();
}
}
Comenzaremos creando un objeto (entidad) Tarea con asignado valores a sus atributos gracias a los método 'setters'. En este punto Doctrine 2 no sabe nada del objeto Entidad. Es únicamente cuando hacemos una llamada a $manager->persist($Tarea1) cuando se informa a Doctrine 2 que inicie la gestión de este objeto entidad.
Es importante señalar que si bien Doctrine 2 ya está al tanto del objeto entidad, aún no lo ha guardado en la base de datos. Para ello se requiere una llamada a $manager->flush(). El método flush provoca que Doctrine 2 realmente interactúe con la base de datos y lleve a cabo las acciones en todas las entidades que está gestionando.
Finalmente cargaremos las Fixtures en la base de datos y comprobaremos su correcta inserción:
php app/console doctrine:fixtures:load
Este comando borrará la posible información que haya en las tablas relacionadas con las Fixtures cargadas. Si lo que se desea es añadir, hay que usar la opcion --append en el anterior comando.
Entradas relacionadas
Lista de tareas simple con Symfony 2: Parte 2
Lista de tareas simple con Symfony 2: Parte 3
Lista de tareas simple con Symfony 2: Parte 4
Lista de tareas simple con Symfony 2: Parte 5Introducción a Symfony 2
Guía de instalación de un sistema LAMP
No hay comentarios:
Publicar un comentario