CakePHP 1.3.4 $ pertenencia
-
25-09-2019 - |
Pregunta
Tengo una tabla llamada user_relationship. que tiene dos claves extranjeras que se refieren a la tabla de usuarios para mapear que son amigos.
CREATE TABLE `user_relationships` (
`id` int(11) unsigned NOT NULL auto_increment,
`status` varchar(255) default 'pending',
`time` datetime default NULL,
`user_id` int(11) unsigned NOT NULL,
`friend_id` int(11) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `fk_user_relationships_users1` (`user_id`),
KEY `fk_user_relationships_users2` (`friend_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
Cuando trato de hornearlo naturalmente no entiende que el amigo_id tiene que referirse al módulo de usuario. Quiero manual editar el código, pero o tengo algunos problemas para entender qué partes editar en lo siguiente
var $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'Friend' => array(
'className' => 'Friend',
'foreignKey' => 'friend_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
En esta parte del código quiero referir el amigo_id a la tabla de usuarios
'Friend' => array(
'className' => 'Friend',
'foreignKey' => 'friend_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
Intenté hacer esto ... ¿Necesito cambiar algo más?
'Friend' => array(
'className' => 'Friend',
'foreignKey' => 'user_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
Solución
¿Qué tal esto?
class UserRelationship {
var $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id'
),
'Friend' => array(
'className' => 'User',
'foreignKey' => 'friend_id'
)
);
}
class User {
var $hasAndBelongsToMany = array(
'Friend' => array(
'className' => 'User',
'joinTable' => 'user_relationships',
'foreignKey' => 'user_id',
'associationForeignKey' => 'friend_id',
'with' => 'UserRelationship'
)
);
}
Se pueden ver asociaciones desde diferentes puntos de vista:
User <- Relationship -> User
| | |
hasMany belongsTo |
Relationship <- User (user_id) hasMany
| User (friend_id) -> Relationship
| |
HABTM HABTM
User <----------------------> User
Su diseño "físico", es decir, esquema de base de datos, es User -> Relationship -> User
. Tu verdadera relación deseada es una User -> User
Sin embargo, la relación. Técnicamente eso se traduce en un User hasAndBelongsToMany User
Asociación (también llamada muchos a muchos). Dado que utiliza tres modelos, se puede dividir una asociación de muchos a muchos:
- El usuario ha pertenencia/relación ha pertenecido al usuario
- Relación pertenencia al usuario/usuario
No necesitar La Asociación Hasandbelongstomany, pero es lo que realmente quieres. Realmente no necesitas el modelo de relación en absoluto, ya que es solo un modelo de ayuda para conectar a los dos usuarios, pero si tú hacer Desea especificar sus asociaciones también, tiene dos asociaciones pertenecientes.
Otros consejos
Your classname for 'Friend' is wrong. Since you have no table "friends" there is no model "Friend" and you have the refer to the class "User" since they share the same table.
'Friend' => array(
'className' => 'User',
'foreignKey' => 'friend_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
I was able to get away with the following:
class User extends AppModel {
var $hasAndBelongsToMany = array(
'Friends1' => array(
'className' => 'User',
'joinTable' => 'friends',
'foreignKey' => 'user_id',
'associationForeignKey' => 'friend_id',
'with' => 'Friend'
),
'Friends2' => array(
'className' => 'User',
'joinTable' => 'friends',
'foreignKey' => 'friend_id',
'associationForeignKey' => 'user_id',
'with' => 'Friend'
)
);
function afterFind(array $results) {
// Merge both sides of the relationship into one alias
foreach ($results as $key=>$result) {
if (isset($result["Friends1"]) && isset($result["Friends2"])) {
$results[$key]["Friends"] = array_merge($result["Friends1"], $result["Friends2"]);
unset($results[$key]["Friends1"]);
unset($results[$key]["Friends2"]);
}
}
It's messy, but you get the idea: grab both sides of the relationship, then merge them after a database read :)