CakePhp 1.3.4 $ pertencem o problema, o caso da tabela de relacionamento
-
25-09-2019 - |
Pergunta
Eu tenho uma tabela chamada user_relationship. que tem duas chaves estrangeiras, referindo -se à tabela de usuários para mapear que são 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 ;
Quando tento assar naturalmente não entende que o amigo_id precisa se referir ao módulo do usuário. eu quero manual editar o código, mas o tenho algum problema para entender quais partes editar no seguinte
var $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'Friend' => array(
'className' => 'Friend',
'foreignKey' => 'friend_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
Nesta parte do código, quero referir o amigo_id para a tabela de usuários
'Friend' => array(
'className' => 'Friend',
'foreignKey' => 'friend_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
Eu tentei fazer isso .. eu preciso mudar mais alguma coisa?
'Friend' => array(
'className' => 'Friend',
'foreignKey' => 'user_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
Solução
Que tal agora?
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'
)
);
}
Associações podem ser vistas de diferentes pontos de vista:
User <- Relationship -> User
| | |
hasMany belongsTo |
Relationship <- User (user_id) hasMany
| User (friend_id) -> Relationship
| |
HABTM HABTM
User <----------------------> User
Seu layout "físico", ou seja, esquema de banco de dados, é User -> Relationship -> User
. Seu relacionamento real desejado é um User -> User
relacionamento embora. Tecnicamente isso se traduz em um User hasAndBelongsToMany User
Associação (também chamada de muitos para muitos). Como usa três modelos, uma associação de muitos para muitos pode ser dividida em:
- Usuário HasMany Relacionamento/Relacionamento Pertence Usuário
- Relacionamento pertence o usuário/usuário HasMany Relationship
Você não precisar A Associação Hasandbelongstomany, mas é o que você realmente quer. Você realmente não precisa do modelo de relacionamento, já que é apenas um modelo auxiliar para conectar os dois usuários, mas se você Faz Deseja especificar suas associações também, ele tem duas associações pertencentes.
Outras dicas
Seu nome de classe para 'amigo' está errado. Como você não tem "amigos" da tabela, não há modelo "amigo" e você tem o "usuário" de referência à classe, pois eles compartilham a mesma tabela.
'Friend' => array(
'className' => 'User',
'foreignKey' => 'friend_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
Consegui me safar do seguinte:
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"]);
}
}
É bagunçado, mas você entendeu: pegue os dois lados do relacionamento, depois mesclá -los após um banco de dados ler :)