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' => ''
    )
Foi útil?

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 :)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top