Entidades en Drupal

Posteado el por: moncada.nicolas
FacebookTwitter
logo drupal

A partir de Drupal 7 se empieza a usar el concepto de entidades, permitiéndole al programador poder representar los objetos de su proyecto de una forma estándar en el sistema. Gracias a esto y a la funcionalidad de adjuntar campos (Fields), hace que Drupal se convierta en una alternativa totalmente escalable para desarrollar complejos sistemas.

Para quienes han trabajado mucho con Drupal, sabrán que se puede hacer casi cualquier proyecto usando Nodos, Usuarios, Términos de Taxonomías y/o Comentarios. Cada uno de estos están definidos como entidades, es por eso que se les pueden adjuntar campos para extender la información que pueden portar. No obstante, dependiendo del proyecto, puede no ser la mejor opción la de explotar tanto estas entidades (sobre todo a los Nodos), posiblemente por rendimiento, eficiencia, u otro argumento, y pueda ser la oportunidad de resolver el proyecto creando nuestras propias entidades. Pero ¿Cuándo debería crear mi propia entidad y no usar Nodos? ¿Por qué debería hacerlo? ¿Qué puedo ganar haciéndolo? La idea de éste post es poder aclarar estas interrogantes analizando un problema simple a resolver, luego explicando técnicamente las entidades, como se crean, que módulos lo usan, etc...

Nodos versus Entidad Personalizada

La mejor forma de poder responder las preguntas hechas anteriormente es analizando un problema que debamos resolver con Drupal y ver como se desarrollaría usando solo Nodos contra la otra opción de crear una entidad y en que se diferenciarán finalmente. A continuación el problema:

Se solicita tener un mantenedor de locales de una empresa. Cada local tiene un nombre, un responsable (un texto simple), una dirección (un texto) y una fecha de apertura. También se solicita poder registrar la cantidad de trabajadores que trabajan en cada local. Adicionalmente se identifica que existen dos tipos de locales, los cuales son alpha y beta. Cada una de estas deben registrar información adicional correspondiente a su tipo.

A continuación las propuestas de desarrollo:

Opción 1: Nodos

Usando esta opción los locales se registrarán en la tabla "node", sabiendo esto procedemos a identificar y crear los dos tipos de contenidos: Local Alpha y Local Beta. En cada uno de estos tipos de contenidos les creamos los siguientes campos "compartidos":

  • Responsable
  • Dirección
  • Fecha de Apertura
  • Cantidad de Trabajadores

Se usa el título del nodo para definir el nombre del local.
Y finalmente, en cada tipo de contenido les adjuntamos los campos faltantes según lo definido en cada tipo de local.

Opción 2: Entidades

Creamos una entidad llamada Local que se registrará en la tabla "local", la cual cuenta con las siguientes columnas:

  • lid: Identificador del local
  • nombre: Nombre del local
  • direccion: Dirección del local
  • responsable: Responsable del local
  • apertura: Fecha de apertura
  • trabajadores: Cantidad de Trabajadores

Luego le creamos dos bundles (símil a tipos de contenidos de los nodos), llamados Alpha y Beta. A cada uno se le adjunta los campos correspondiente a su tipo (Usando el sistema de Fields).

Resultado

En ambos casos solucionamos el pedido pero con diferencias en el como se desarrollan y en el rendimiento final. En primer lugar, con la opción 1 solo necesitamos conocer el interfaz de usuario de Drupal para resolver el pedido, no necesitamos escribir una sola línea de código. En cambio, con la opción 2, sería imposible no tener que hacerlo (incluso usando ECK no sería suficiente, por las propiedades/columnas especificas que se solicitan).

Sin embargo, en términos de rendimiento la opción 2 resulta ser más efectivo, para entenderlo podemos ver un ejemplo de como funcionaría el sistema cuando le solicitamos la lista de locales y que nos muestre el nombre, la dirección, el responsable y la cantidad de trabajadores.

Con la opción 1 la query a la base de datos sería así:

SELECT
  n.title,
  d.field_direccion_value,
  r.field_responsable_value,
  t.field_trabajadores_value
FROM node as n
LEFT JOIN field_data_field_direccion as d ON d.entity_id = n.nid AND d.entity_type = 'node'
LEFT JOIN field_data_field_responsable as r ON r.entity_id = n.nid AND r.entity_type = 'node'
LEFT JOIN field_data_field_trabajadores as t ON t.entity_id = n.nid AND t.entity_type = 'node'
WHERE n.type IN ('local_alpha', 'local_beta')
LIMIT 10

En cambio con la opción 2 sería así:

SELECT nombre, direccion, responsable, trabajadores FROM local
LIMIT 10

La diferencia es que con la opción 1 se tuvo que hacer JOINS para mostrar los valores que, en teoría, todo local debería tener, mientras que en el otro no necesita hacerlo. Por lo tanto se usa menos recursos con la opción 2 que con la 1 y se notaría más cuando la cantidad de campos sea más elevada. Consideren que por cada campo creado con el sistema Fields se generan 2 tablas, una que registra el valor actual que tiene la entidad y otro que registra las revisiones/historial.

En resumen

Como mencione en un principio, dependiendo del proyecto podría ser bueno cuestionarse si usamos una opción u otra (o incluso combinadas). Si el proyecto tiene que ver con noticias, documentación, o similares no dudaría en usar Nodos, pero si hablamos de un proyecto de características más administrativas, de procedimientos, de sistemas de información en general, entonces es cuando se debe hacer el análisis:

  • Si necesitas desarrollar en tiempo record, usa Nodos (Por último servirá de prototipo). Pero si el concepto de entidades te llama mucho la atención prueba usando ECK.
  • Si en el proyecto se identifica que se requieren muchos campos, sobre los 50 por ejemplo, personalmente ya consideraría ver la opción de usar entidades. El servidor y el tiempo del usuario/cliente final te lo agradecerán.

¿Cómo se crean Entidades?

NOTA: Recomiendo 100% que tengan considerado instalar el módulo Entity API, este extiende el sistema core de Drupal, facilitando que nuestras entidades se integren automáticamente con módulos como Views, Rules, Panels, entre otros.

Para decirle a Drupal sobre la existencia de una entidad es necesario implementar un hook (una función), que la describa como tal, la cual se llama hook_entity_info(). Aquí es donde indicamos, como mínimo, lo siguiente:

  • Nombre de la Entidad.
  • Si se le puede Adjuntar Campos. (Si, puede que algunas entidades no quieras extenderlas con fields.)
  • La tabla en donde se guardarán los datos.
  • Modos para verlo.
  • Los Bundles.

A continuación se explicarán las características de las entidades.

Bundles

Los Bundles es la forma de definir un sub tipo de la entidad y son a estos a los que se les adjuntan campos. Como lo indicamos anteriormente, los bundles de la Entidad Nodo son teóricamente los tipos de contenido. En el caso de Usuario, solo existe un Bundle, llamado User (Igual que la entidad), ya que sin un Bundle, no hay forma de adjuntarle campos. Si la entidad cuenta con más de un bundle es necesario definir la columna que lo defina, por ejemplo para los Nodos, la columna "type" cumple con dicha función (En el hook_entity_info() defines el nombre de la columna). En el caso de Usuario no se requiere ya que siempre será un bundle llamado "User".

Campos

Ya lo vimos en acción antes, pero es necesario mencionarlo nuevamente. Los campos, son para guardar información adicional a las entidades. Cada campo tiene una configuración base y una configuración de instancia. Esta última nos permite reutilizar campos en distintos bundles sin importar la entidad pero compartiendo la configuración base (Por ejemplo la estructura en la base de datos.)

Propiedades

Las propiedades, técnicamente hablando, son las columnas de la tabla que usa la entidad (Descartando el identificador y la columna que se usa para definir el bundle). Recordando la Opción 2 del problema que se analizó más arriba, las propiedades serían el nombre, dirección, responsable, apertura y trabajadores. En cambio la entidad Nodo tiene como propiedad el título, el estado si esta publicado o no, etc.

Las propiedades no se definen en el hook_entity_info(), se deben definir aparte, con ayuda de un hook llamado hook_entity_property_info_alter() (del módulo Entity api) que nos permite alterar la forma en que se representan en el sistema. Por ejemplo la fecha de apertura del local lo guardamos como un entero en la base de datos (Formato timestamp) y con ayuda del hook podemos definir que es del tipo Fecha (date).

¿Cuáles módulos usan Entidades?

De los grandes módulos contribuidos que usan entidades son:

  • Drupal Commerce: Todo el sistema de productos, ordenes, elemento en el carro, perfiles de cliente, entre otros, están representados como entidades.
  • Rules: Todas las configuraciones de las reglas se guardan como entidades.
  • ECK
  • Profile 2
  • Message
  • Bean
moncada.nicolas

Últimos Comentarios

Blog

En esta sección compartimos algunas experiencias concretas para la comunidad de desarrolladores de código abierto

Hace un tiempo atrás, Transbank (la empresa detrás de Webpay) había habilitado una nueva modalidad para integrar su sistema de pago con nuestros sitios. Se trata de un servicio web que utiliza el protocolo SOAP, haciendonos más fácil la integración con respecto a su antecesor. Y para soportar esto en Drupal, se ha publicado una nueva versión del módulo Webpay y aquí veremos como funciona.

Posteado el por: moncada.nicolas

Para la junta de Drupal (realizado el 20 de Diciembre del 2016) he presentado el desarrollo de un módulo pensado para la comunidad de Drupal Chile, llamado Badge. El objetivo del módulo es crear logros o insignias y asignarlo a usuarios u otras entidades de nuestro sitio.