5

我有两个表,username两者都有字段。如何为本地表和外部表指定字段名称?

我希望 CakePHP 会做类似的事情

ON (`T1`.`username` = `T2`.`username`)`

结果。在没有任何更改的情况下,表将按照以下条件连接:

ON (`T1`.`id` = `T2`.`t1_id`)`

设置'foreign_key' = 'username'属性是不够的,因为它会产生这样的查询:

ON (`t1`.`id` = `t2`.`username`)`

我有两个解决方案。第一个是使用'join'属性和动态连接表。在这种情况下,我可以设置本地和外国字段。但是,如果我需要将更多表加入到那个表中,手动加入,我不能再使用包含我需要手动编写以下连接,即使该关联设置正确。所以我每次都需要编写长连接定义而不是只使用'contain' => array('T1', 'T2', 'T3')

其次是将表的'primary_key'设置为相应的字段。它可以在模型文件或运行时完成。在我的情况下,它不能在模型中完成,因为该表的字段也具有“正确”关联'id'。设置它运行时就是这种情况,但我不喜欢它,因为它不明显并且看起来像一个黑客。

当我问这个问题时,我以为我遗漏了一些明显的东西,但现在我明白 CakePHP 无法做到这一点。所以我开始赏金,希望有人分享解决方案。如果不是,我将尝试阅读蛋糕源并重新定义模型一些方法以添加'foreign_key'在关联定义附近定义本地字段的能力。

4

5 回答 5

14

外键假

在连接条件中建立一个不使用相关模型的主键的关联——标准的方法是使用'foreignKey' => false.

即,而这个关联:

class Comment extends AppModel {
    public $belongsTo = array(
        'Profile' => array(
        )
    );
}

将生成此 sql:

SELECT ... LEFT JOIN profiles on ON (Profile.id = Comment.profile_id)

指定不要像这样使用 foreignKey:

class Comment extends AppModel {
    public $belongsTo = array(
        'Profile' => array(
            'foreignKey' => false
        )
    );
}

将产生这个(无效的)sql:

SELECT ... LEFT JOIN profiles on ON ()

从这一点开始,可以使用条件数组键指定所需的条件:

class Comment extends AppModel {
    public $belongsTo = array(
        'Profile' => array(
            'foreignKey' => false,
             'conditions' => array(
                 'Comment.username = Profile.username'
             ),
        )
    );
}

(请注意,条件定义为字符串)导致:

 SELECT ... LEFT JOIN profiles on ON (Comment.username = Profile.username)
于 2014-03-04T08:55:39.127 回答
6

更新:

只需指定您不想使用foreignKey,然后指定条件(都在关联内:

'foreignKey' => false'conditions' => 'Comment.username = User.username'

PS - 向前迈进可能是一个好主意,尽量不要对帮助你的人无礼。


这在 CakePHP 书中有非常明确的定义:http: //book.cakephp.org/2.0/en/models/associations-linking-models-together.html#hasmany

class User extends AppModel {
    public $hasMany = array(
        'Comment' => array(
            'className' => 'Comment',
            'foreignKey' => 'user_id', // <---- THIS HERE you can define the foreign_key
            'conditions' => array('Comment.status' => '1'),
            'order' => 'Comment.created DESC',
            'limit' => '5',
            'dependent' => true
        )
    );
}

什么是外键?

在关系数据库的上下文中,外键是一个表中的一个字段,它唯一地标识另一个表的一行。

于 2013-11-11T16:23:33.643 回答
3

当您想要检索用户及其所有评论时,这只是一种适用于您的 hasMany 关系的解决方法

class User extends AppModel {
    public $hasMany = array(
        'Comment' => array(
            'finderQuery' => 'SELECT * FROM comments Comment 
                              LEFT JOIN users User 
                              ON Comment.username = User.username 
                              WHERE User.id = {__CakeID__}'
        )
    );
}

希望能帮助到你

于 2014-03-04T07:20:17.820 回答
1

我为这个确切的问题苦苦挣扎了好几天,我找到的解决方案(上面没有明确解决)是:hasMany必须有'foreignKey' => false,而belongsTo必须也有,'foreignKey' => false并且有'conditions' => 'Comment.username = User.username'. 使用conditions作为字符串而不是关联数组。像这样:

// Profile
public $hasMany = array(
    'Comment' => array(
        'foreignKey' => false,
    )
);

// Comment
public $belongsTo = array(
    'Profile' => array(
        'foreignKey' => false,
        'conditions' => array('Profile.username = Comment.username')
    )
);
于 2014-07-17T16:21:49.727 回答
0
public $hasMany = array(
    'Comment' => array(
        'className' => 'T1',
        'foreignKey' => 'username',
        'dependent' => true
    )
);

请注意,当从蛋糕中删除 T2 时,从属 true 将删除所有 T1。

于 2013-11-11T17:36:20.843 回答