Ver Mensaje Individual
  #1 (permalink)  
Antiguo 10/10/2010, 08:40
Avatar de mayid
mayid
Colaborador
 
Fecha de Ingreso: marzo-2009
Ubicación: BsAs
Mensajes: 4.014
Antigüedad: 15 años, 8 meses
Puntos: 101
Busqueda JOINS en CAKE

Hace un tiempo vengo penando con las consultas en CAKE, a la hora de relacionar tablas.

Las tablas que tengo son:
users
words
users_words
friends ( o users_users)

Lo que necesito es una consulta que me devuelva:
- los datos del usuario
- sus palabras asociadas
- sus amigos
- las palabras de sus amigos, en lo posible.

Intente con find y recursividad 2. Pero no puedo obtener las palabras de los amigos por un lado. Y por el otro, la profundida de words es exagerada (me devuelve tambien users_words recursivamente).

Luego intenté con Containable y 'fields' para restringir la busqueda (sin recursividad). Pero el resultado era casi el mismo! Demasiada recursividad en words, y un array vacio en friends-> words.

Ahora estoy intentando con joins. Pero obtengo los mismos resultados recursivos, etc. (es cierto que no llegue a declarar fields especificos).

Esta es la consulta con JOINS:

Código PHP:
Ver original
  1. $options['conditions'] = array(
  2.                 'User.id' => $id
  3.             );
  4.             $options['joins'] = array(
  5.                 array(
  6.                     'table' => 'friends',
  7.                     'alias' => 'users_users',
  8.                     'type' => 'INNER',
  9.                     'conditions' => array(
  10.                         'User.id = users_users.user_id'
  11.                     )
  12.                 ),
  13.                 array(
  14.                     'table' => 'users',
  15.                     'alias' => 'Friend',
  16.                     'type' => 'INNER',
  17.                     'conditions' => array(
  18.                         'users_users.user_id = Friend.id'
  19.                     )
  20.                 ),
  21.                 array(
  22.                     'table' => 'users_words',
  23.                     'alias' => 'UsersWords',
  24.                     'type' => 'INNER',
  25.                     'conditions' => array(
  26.                         'User.id = UsersWords.user_id'
  27.                     )
  28.                 ),
  29.                 array(
  30.                     'table' => 'words',
  31.                     'alias' => 'Word',
  32.                     'type' => 'LEFT',
  33.                     'conditions' => array(
  34.                         'UsersWords.word_id = Word.id'
  35.                     ),
  36.                     'fields' => array(
  37.                         'Word.id',
  38.                         'GROUP_CONCAT(Word.id ORDER BY Word.id) as id',
  39.                         'Word.description'                     
  40.                     )                  
  41.                 )
  42.             );
  43.             //$options['group'] = array('users.id');
  44.            
  45.             $user_relations = $this->User->find('first', $options);

Lo de GROUP_CONCAT puede no ir. Es solo que pensé que me las ingeniaría para obtener un listado de usuarios separados por comas, y lo mismo con las palabras. Pero ahora que lo pienso, necesito tanto el id como el nombre de ambas tablas.

En fin, el array que suelo obtener con las consultas en mas o menos este:

Código PHP:
Ver original
  1. (
  2.     [User] => Array
  3.         (
  4.             [id] => 1
  5.             [username] => admin
  6.             [password] => e714044c058d932bac9a63f7f00273dbce722794
  7.             [email] => gperez@agendajoven.org.ar
  8.             [photo] => anonimo.gif
  9.         )
  10.  
  11.     [Friend] => Array
  12.         (
  13.             [0] => Array
  14.                 (
  15.                     [id] => 4
  16.                     [user_id] => 1
  17.                     [friend_id] => 2
  18.                 )
  19.  
  20.             [1] => Array
  21.                 (
  22.                     [id] => 6
  23.                     [user_id] => 1
  24.                     [friend_id] => 3
  25.                 )
  26.  
  27.         )
  28.  
  29.     [Word] => Array
  30.         (
  31.             [0] => Array
  32.                 (
  33.                     [id] => 6
  34.                     [name] => corredor
  35.                     [description] =>
  36.                     [UsersWord] => Array
  37.                         (
  38.                             [id] => 6
  39.                             [user_id] => 1
  40.                             [word_id] => 6
  41.                             [points] => 1
  42.                             [description] =>
  43.                         )
  44.  
  45.                 )
  46.  
  47.             [1] => Array
  48.                 (
  49.                     [id] => 11
  50.                     [name] => cacharro
  51.                     [description] =>
  52.                     [UsersWord] => Array
  53.                         (
  54.                             [id] => 11
  55.                             [user_id] => 1
  56.                             [word_id] => 11
  57.                             [points] => 1
  58.                             [description] =>
  59.                         )
  60.  
  61.                 )
  62.  
  63.             [2] => Array
  64.                 (
  65.                     [id] => 12
  66.                     [name] => esteban
  67.                     [description] =>
  68.                     [UsersWord] => Array
  69.                         (
  70.                             [id] => 12
  71.                             [user_id] => 1
  72.                             [word_id] => 12
  73.                             [points] => 1
  74.                             [description] =>
  75.                         )
  76.  
  77.                 )
  78.  
  79.         )
  80.  
  81. )

Pero el que quisiera obtener sería mas o menos así:

Código PHP:
Ver original
  1. (
  2.     [User] => Array
  3.         (
  4.             [id] => 1
  5.             [username] => admin
  6.             [password] => e714044c058d932bac9a63f7f00273dbce722794
  7.             [email] => gperez@agendajoven.org.ar
  8.             [photo] => anonimo.gif
  9.         )
  10.  
  11.     [Friend] => Array
  12.         (
  13.             [0] => Array
  14.                 (
  15.                     [id] => 4
  16.                     [friend_id] => 2
  17.                     [Word] => Array
  18.                     (
  19.                         [0] => Array
  20.                             (
  21.                                 [id] => 6
  22.                                 [name] => corredor
  23.                                 [description] =>
  24.                             )
  25.                 )
  26.  
  27.             [1] => Array
  28.                 (
  29.                     [id] => 6
  30.                     [friend_id] => 3
  31.                     [Word] => Array
  32.                     (
  33.                         [0] => Array
  34.                             (
  35.                                 [id] => 6
  36.                                 [name] => corredor
  37.                                 [description] =>
  38.                             )
  39.                 )
  40.  
  41.         )
  42.  
  43.     [Word] => Array
  44.         (
  45.             [0] => Array
  46.                 (
  47.                     [id] => 6
  48.                     [name] => corredor
  49.                     [description] =>
  50.                 )
  51.  
  52.             [1] => Array
  53.                 (
  54.                     [id] => 11
  55.                     [name] => cacharro
  56.                     [description] =>
  57.                     )
  58.  
  59.             [2] => Array
  60.                 (
  61.                     [id] => 12
  62.                     [name] => esteban
  63.                     [description] =>
  64.                 )
  65.  
  66.         )
  67.  
  68. )

Agradezco que me den una pista de como seguir.