Relacion en views?

mariano.barcia's picture

Estimada drupalgente,

Tengo un sistema, con 2 tipos de entidades nodos (A y B), relacionados a través de una tabla (custom) de relación.

Es decir, la relación entre 2 nodos A y B está dada por esta tabla.

Esto resulta en que no estoy pudiendo construir una view que, para un nodo A me retorne el listado de los nodos B relacionados.

Alguno sabe si puedo exponer esa tercer tabla una "relationship" en views?

Gracias por cualquier dato que pudieran aportar :-)

Grupos:
Login or register to post comments

Podrias usar el modulo Table

dagmar's picture
dagmar - Mié, 2010-06-16 12:30

Podrias usar el modulo Table Wizard, que crea automaticamente los handlers para las relaciones de las tablas que elijas.

En la sección Basic Usage de la documentación: http://drupal.org/node/452374 se explica como lograr esto.

Saludos

Mariano D'Agostino
http://cuencodigital.com


Gracias mariano por la

mariano.barcia's picture
mariano.barcia - Mié, 2010-06-16 12:51

Gracias mariano por la info.

Te cuento que ya intentamos con TW y no funcionó. La razón es que en realidad, no tenemos una entidad "custom" sino solo la relación. Las dos entidades conviven en la tabla nodes, en la cual tenemos 2 tipos de nodos, y solo tenemos la tabla de relación. No pudimos resolver esto, porque TW va a apuntado a esos módulos que definen sus propias entidades, y no a nodos representados en la tabla node.

Alguna otra pista? Hacerlo por código con los hooks de views?
Gracias de nuevo.


En realidad, quiero armar una

mariano.barcia's picture
mariano.barcia - Mié, 2010-06-16 13:25

En realidad, quiero armar una view para alimentar un nodereference. Y estoy pensando, que tal vez sea mejor saltear la views, y en vez de hacerlo "server-side" hacerlo "client-side". Mi idea sería utilizar javascript, y realizar una llamada y reemplazar los valores del input del formulario del nodereference con valores de una consulta SQL directa (a la manera que lo hace autocomplete). Qué les parece? A mí me parece que va a ser más fácil que intentar construir una relationship custom por código...


No entiendo muy bien la

Alexander N's picture
Alexander N - Mié, 2010-06-16 14:23

No entiendo muy bien la funcionalidad que buscas, pero si te instalás el Advanced Help y luego vas a tu Drupal en /help/views/api-tables tienes la guía para exponer los fields de una tabla con el API de Views.

Yo lo hice un par de veces pero sólo cuando no tuve otra opción, el resto de las veces es mejor usar CCK y node reference.

Por ejemplo suponiendo que hay una tabla custom "Relaciones" que tiene solamente NIDs de relaciones 1:1 entre nodos.

create table relaciones (nida int(10) not null, nidb int(10) not null, primary key (nida, nidb));

podrías hacerte tu propio MIMODULO.views.inc, con:

<?php
function MIMODULO_views_data() {
 
$data['relaciones'] = array(
   
'table' => array(
     
'group' => 'Relaciones custom',
     
'join' => array(
       
'node' => array(
         
'left_field' => 'nid',
         
'field' => 'nida',       
         ),
      ),
    ),
   
'nida' => array(
     
'title' => t('NID A'),
     
'help' => t('NID A.'),
     
'field' => array(
       
'handler' => 'views_handler_field_node',
       
'click sortable' => TRUE,
      ),
     
'relationship' => array(
       
'handler' => 'views_handler_relationship',
       
'base' => 'node',
       
'base field' => 'vid',
       
'label' => t('Relacion custom A'),
      ),
     
'filter' => array(
       
'handler' => 'views_handler_filter_numeric',
      ),
    ),
   
'nidb' => array(
     
'title' => t('NID B'),
     
'help' => t('NID B.'),
     
'field' => array(
       
'handler' => 'views_handler_field_node',
       
'click sortable' => TRUE,
      ),
     
'filter' => array(
       
'handler' => 'views_handler_filter_numeric',
      ),
     
'relationship' => array(
       
'handler' => 'views_handler_relationship',
       
'base' => 'node',
       
'base field' => 'vid',
       
'label' => t('Relacion custom B'),
      ),
    ),
  );
  return
$data
}
?>

Y eso te expone los fields de tu tabla para usar como filters y relationship (estoy asumiendo que quieres hacer algo como "filtro por nid A pero muestro el contenido del nodo con nid B").

Lo único es que, en mi experiencia con Drupal, cuando llego a hacer algo como esto es indicación de que Views quizás no sea la solución.


Muchas gracias, muy detallada

mariano.barcia's picture
mariano.barcia - Mié, 2010-06-16 22:43

Muchas gracias, muy detallada tu ayuda alexander N!

Parece ser la solución, voy a tener que probarla :-) aviso mañana como me ha ido, gracias de nuevo.


No problem. Y recuerda

Alexander N's picture
Alexander N - Jue, 2010-06-17 00:00

No problem. Y recuerda implementar hook_views_api() en el .module (el código que puse antes va en un .views.inc en el root dir de tu módulo, a menos que indiques lo contrario en tu hook_views_api()) para que Views le preste atención a lo que hace tu módulo.


tarde pero seguro, funcionó

mariano.barcia's picture
mariano.barcia - Dom, 2010-10-17 21:34

tarde pero seguro, funcionó muy bien todo. Cuando me puse a codificar con este ejemplo, me di cuenta que no era tan complicado y la relación que se quería era binaria y no ternaria, lo cual simplificó las cosas de entrada.

Cómo es la tabla en la BD?

La tabla es example_relationship, y tiene dos campos parent_nid y child_nid. Tanto parent_nid como child_nid son nodos.

Cuál es el nuevo código a agregar?

Este código va en el example_views.inc (en el .module va el hook_views_api() como bien apuntaste Alejandro).

/**
* Implementation of hook_views_data()
*
* hook_views_data tells the views module where to look for data.
*
*/

function example_views_data() {
  $data['example_relationship'] = array(
    'table' => array(
      'group' => t('example'),
      'join' => array( // esta parte es clave para que la view arme la consulta correctamente
        'node' => array( // que haga un join a node y haga coincidir el nid con el child_nid
          'left_field' => 'nid',
          'field' => 'child_nid',               
        ),
      ),
    ),
    'parent_nid' => array(
      'title' => t('nid parent'),
      'help' => t('nid del parent'),
      'field' => array(
        'handler' => 'views_handler_field_node',
        'click sortable' => TRUE,
      ),
      'filter' => array(
        'handler' => 'views_handler_filter_numeric',
      ),
      // Information for accepting a nid as an argument
      'argument' => array(
        'handler' => 'views_handler_argument_node_nid',
        'name field' => 'title', // the field to display in the summary.
        'numeric' => TRUE,
        'validate type' => 'nid',
      ),
    ),
    'child_nid' => array(
      'title' => t('nid child'),
      'help' => t('nid del child'),
      'field' => array(
        'handler' => 'views_handler_field_node',
        'click sortable' => TRUE,
      ),
      'filter' => array(
        'handler' => 'views_handler_filter_numeric',
      ),
    ),
  );
 
  return $data;
}

Nota

En otro contexto, una relación así podría hacerse con nodereference, pero en el caso de este proyecto los child nodes son "clases" de cosas que no se instancian cada vez, sino que están fijos (a.k.a. singletons) y se asignan a parent_nodes (que sí se van creando nuevos).

Cómo utilizar el nuevo código?

Luego en la view, hay que agregar un argumento (que aparece dentro del grupo "example"). Un truco más aquí es proveer un "default argument" con "Node ID from URL" o "Current group node from context". Utilizando el NID from URL, el siguiente URL de la view (asumiendo un path "children_of") puede listar todos los children relacionados a un parent cuyo nid sea 81
http://example.com/children_of/81

Espero que sirva el ejemplo, muchas gracias de nuevo a Alejandro!
Salud,