Amistades en CakePHP 2.x

Tengo problemas para establecer amistades con CakePHP 2.

Tengo dos tablas de base de datos: usuarios y amigos. Mi tabla de usuarios tiene las siguientes columnas:

  • id
  • email
  • la contraseña

Y la tabla de mis amigos tiene las siguientes columnas:

  • id
  • user_id
  • amigo_id
  • aprobado

Tengo amigos configurados como una relación hasAndBelongsToMany en mi modelo de Usuarios:

<?php
class User extends AppModel {
    public $hasAndBelongsToMany = array(
        'Friends' => array(
            'className' => 'User',
            'joinTable' => 'friends',
            'foreignKey' => 'user_id',
            'associationForeignKey' => 'friend_id',
            'unique' => true
        )
    );
}

Ahora, cuando trato de recuperar amigos para un usuario, solo enumera las amistades que inició el usuario especificado, es decir, donde user_id es igual a la identificación del usuario; no me muestra a mis amigos dónde la otra persona puede haber iniciado la solicitud (es decir, dónde está la ID del usuario actual en el friend_id columna).

¿Cómo puedo buscar amigos, para registrar dónde está el user_id or friend_id columna es igual a un ID en particular?

preguntado el 30 de junio de 12 a las 22:06

1 Respuestas

No creo que entiendas cómo funciona HABTM. Leer esta parte del libro. Necesitará una tabla de amigos_usuarios además de las tablas que tiene para que la relación funcione. Creo que si fuera a configurarlo de esta manera, necesitaría definir una Amistad como tener y pertenecer a muchos Usuarios.

Sin embargo, me pregunto si con su configuración actual desea una relación HABTM. parece un usuario tiene muchas amigos, y eso es todo. Considere el uso de esa relación y le dará la identificación relevante como espera. No olvides definir Amigo pertenece a Usuario.


Aquí comienza mi tutorial canónico de Cake 2.0 Amistad. Descargué cakePHP 2.1, así que tuve un nuevo comienzo. Primero cambié mi sal y cifrado de seguridad, luego agregué mi conexión a la base de datos. Luego estructuré mi base de datos de la siguiente manera:

base de datos:

users mesa:

id         | int(11)
created    | datetime
username   | varchar(255)

friendships mesa:

id         | int(11)
user_from  | varchar(255)
user_to    | varchar(255)
created    | datetime
status     | varchar(50)

Obviamente, su tabla de usuarios puede/tendrá más cosas, pero esto es lo mínimo que necesitaba.

Modelos:

Bien, esta es la parte difícil. Aquí está la relación que definí en mi modelo de Usuario.

class User extends AppModel {
/* Other code if you have it */
        var $hasMany = array(
          'FriendFrom'=>array(
             'className'=>'Friendship',
             'foreignKey'=>'user_from'
          ),
          'FriendTo'=>array(
             'className'=>'Friendship',
             'foreignKey'=>'user_to'
          )
       );
       var $hasAndBelongsToMany = array(
          'UserFriendship' => array(
              'className' => 'User',
              'joinTable' => 'friendships',
              'foreignKey' => 'user_from',
              'associationForeignKey' => 'user_to'
            )
       );
/* Again, other code */
}

Aquí está mi modelo de amistad:

class Friendship extends AppModel {
/* Other code if you have it */
    var $belongsTo = array(
      'UserFrom'=>array(
         'className'=>'User',
         'foreignKey'=>'user_from'
      ),
      'UserTo'=>array(
         'className'=>'User',
         'foreignKey'=>'user_to'
      )
   );
/* Again, other code */
}

Nota sobre los modelos: El modelo de amistad pertenece a 2 usuarios. El modelo de usuario tiene 3 asociaciones. Las dos relaciones hasMany en el modelo de usuario son alias para acceder a los datos del modelo de amistad, por lo que podemos usar $this->User->FriendTo or $this->User->FriendFrom de los controladores para llegar al modelo de Amistad. Al principio los llamé UserFrom y UserTo, reflejando la configuración del modelo de Amistad, pero Cake lanzó un silbido sobre las similitudes, así que tuve que hacerlos más distintos.

Controladores y Vistas: Horneé controladores y vistas usando la utilidad de horneado. Luego creé dos usuarios (Daniel y Martin) y creé una nueva amistad de Daniel a Martin con un estado de requested. Luego actualicé el estado de la amistad a confirmed.

Creé la siguiente acción de usuario personalizada sin vista para demostrar la recuperación de datos sobre una amistad del UsersController:

public function test() {
  $data = $this->User->FriendFrom->find('all', 
    array(
      'conditions'=>array('user_from'=>1), 
      'contain'=>array('UserTo')
    )
  );
  die(debug($data));
}

Este hallazgo utiliza la relación hasMany del modelo de usuario para acceder al modelo de amistad y obtener el modelo relacionado. user_from y user_to datos para las relaciones donde el usuario con el id de 1 inició las relaciones.

Su hallazgo específico:

Martin, el hallazgo que estás buscando es súper simple bajo este sistema, y ​​aunque podrías hacerlo de otra manera, siempre estarías lidiando con un método similar, siempre y cuando siempre haya dos lados en una relación. Todo lo que tiene que hacer es obtener una lista de relaciones donde su ID de usuario sea usuario1 o usuario2 (en mi caso, solo para saber quién inició la relación, los tengo almacenados como usuario_para y usuario_de; creo que esto es lo que lo intimidó). ). Luego itero a través de toda la matriz, seleccionando los datos de amigos relevantes en función de si soy el usuario 1 o 2 en esa matriz dada. Es un método realmente simple, y simplemente lo puse en mi modelo de usuario. Cambia el dado (debug()); para return $friendslist para poder llamarlo desde su controlador y recuperar una matriz.

public function getFriends($idToFind) {
  $data = $this->FriendFrom->find('all', 
    array(
      'conditions'=>array(
        'OR'=> array(
            array('user_to'=> $idToFind),
            array('user_from'=> $idToFind)
        )
        )
    )
  );
  $friendslist = array();
  foreach ($data as $i) {
    if ($i['FriendFrom']['user_from'] == $idToFind){
        $friendslist[] = $i['UserTo'];
    }
    elseif ($i['FriendFrom']['user_to'] == $idToFind){
        $friendslist[] = $i['UserFrom'];
    }
  }

  die(debug($friendslist));
}

Respondido 02 Jul 12, 04:07

¿Por qué? Los datos de la relación existen en el friends ¿mesa? - Martin Bean

Sí, mirando más a tu pregunta, realmente creo que quieres usar una relación HasMany en lugar de HABTM. - swiecki

¿El amigo también es usuario? En ese caso, tiene una relación HABTM de usuario a usuario, en cuyo caso necesita una tabla de amigos como dijo swiecki: 8vio

Entonces, ¿cómo obtendría registros en los que user_id or friend_id es una identificación en particular? - Martin Bean

Si el usuario tiene muchos amigos, puede hacer una búsqueda en el modelo de amigo como tal, suponiendo que pueda obtener la identificación del usuario actual, digamos, del componente Auth: $myFriends= $this->Friend->find('all',array('conditions' => array('Friend.user_id' => $thisUserId)));. Esto busca amigos en la tabla de amigos donde la identificación de usuario relacionada es la identificación que ingresa. swiecki

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.