【问题标题】:CakePHP 1.3.4 $belongsTo problem incase of Relationship tableCakePHP 1.3.4 $belongs 关系表的问题
【发布时间】:2011-04-17 15:23:02
【问题描述】:

我有一个名为 user_relationship 的表。它有两个外键引用用户表来映射他们是朋友。

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 ;

当我尝试烘焙它时,自然不明白friend_id 必须引用用户模块。我想手动编辑代码,但在理解以下要编辑的部分时遇到了一些问题

var $belongsTo = array(
    'User' => array(
        'className' => 'User',
        'foreignKey' => 'user_id',
        'conditions' => '',
        'fields' => '',
        'order' => ''
    ),
    'Friend' => array(
        'className' => 'Friend',
        'foreignKey' => 'friend_id',
        'conditions' => '',
        'fields' => '',
        'order' => ''
    )
);

在这部分代码中,我想将friend_id 引用到用户表

    'Friend' => array(
        'className' => 'Friend',
        'foreignKey' => 'friend_id',
        'conditions' => '',
        'fields' => '',
        'order' => ''
    )

我试过这样做..我需要改变什么吗?

    'Friend' => array(
        'className' => 'Friend',
        'foreignKey' => 'user_id',
        'conditions' => '',
        'fields' => '',
        'order' => ''
    )

【问题讨论】:

    标签: cakephp associations models cakephp-1.3


    【解决方案1】:

    这个怎么样?

    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'
             )
        );
    
    }
    

    可以从不同的角度看到关联:

    User        <-    Relationship    ->     User
     |                     |                  |
     hasMany           belongsTo              |
     Relationship  <-  User (user_id)        hasMany
     |                 User (friend_id)  ->  Relationship
     |                                        |
     HABTM                                   HABTM
     User       <---------------------->     User
    

    您的“物理”布局,即数据库架构,是User -&gt; Relationship -&gt; User。不过,您真正想要的关系是User -&gt; User 关系。从技术上讲,这转化为User hasAndBelongsToMany User 关联(也称为多对多)。由于它使用三种模型,因此可以将多对多关联分解为:

    • 用户有很多关系/关系属于用户
    • 关系属于用户/用户有很多关系

    您不需要 hasAndBelongsToMany 关联,但它确实是您想要的。您根本不需要关系模型,因为它只是连接两个用户的辅助模型,但如果您确实也想指定它的关联,它有两个 belongsTo 关联。

    【讨论】:

    • 你能解释一下为什么我们需要使用 $hasAndBelongsToMany。我不能用 2 hasMany 完成它吗?
    • 知道了 :D wow.. CakePHP 比我想象的要酷 :D 最初我想在 user_relationship 表中保存两行以便查找() user_relationship(id, user_id,朋友ID,状态)状态正在等待接受等等。使用HABTM我不需要两个条目还是我仍然需要它?
    • @Harsha 不确定你的意思...?
    • 在关系表中 u_r(1, 22, 43, 'pending) u_r(2, 43, 22, 'pending) 一个关系
    • @Harsha 我明白了。如果您希望关系是“双向的”(“朋友”也有“用户”作为朋友),您仍然会遇到这个问题。您需要两个关联(一个通过user_id/friend_id 字段,另一个通过friend_id/user_id),关系表中的两行或一些获取HATBM记录的自定义SQL查询,无论它是否已连接通过user_id/friend_idfriend_id/user_id。所有技术在速度和简单性方面各有利弊。
    【解决方案2】:

    你的“朋友”类名是错误的。由于您没有表“朋友”,因此没有模型“朋友”,并且您可以引用类“用户”,因为它们共享同一个表。

    'Friend' => array(
        'className' => 'User',
        'foreignKey' => 'friend_id',
        'conditions' => '',
        'fields' => '',
        'order' => ''
    )
    

    【讨论】:

    • 非常感谢蒂姆。 'Friend' => array() 指的是什么?
    • 它引用您的用户表并使用“friend_id”作为foreignKey。
    【解决方案3】:

    我能够摆脱以下:

    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"]);
                }
            }
    

    这很混乱,但你明白了:抓住关系的双方,然后在读取数据库后合并它们:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多