简体   繁体   English

如何通过非常规命名的字段将CakePHP中的模型关联起来?

[英]How to associate model in CakePHP by fields not named by convention?

I have two tables with field username in both. 我有两个表,其中包含字段username How i can specify field name for both local and foreign table? 我如何为本地和外国表指定字段名称?

I want CakePHP will do something like 我想CakePHP会做类似的事情

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

in result. 结果。 Without any changes tables will be joined with following condition: 如果没有任何更改,表将加入以下条件:

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

Setting 'foreign_key' = 'username' property is not enough because it will produce query like this: 设置'foreign_key' = 'username'属性是不够的,因为它会产生这样的查询:

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

I have two solutions. 我有两个解决方案。 First one is use 'join' property and join table on the fly. 第一个是使用'join'属性并动态连接表。 In such case i can set both local and foreign field. 在这种情况下,我可以设置本地和外地字段。 But if i need to join more tables to that one, joined manually, i can't use contain anymore i need to write following joins manually even if that associations was set correctly. 但是,如果我需要将更多表连接到那个表,手动加入,我不能再使用包含我需要手动编写以下连接,即使这些关联设置正确。 So i need to write long join definitions every time instead just use 'contain' => array('T1', 'T2', 'T3') 所以我需要每次写长连接定义而不是只使用'contain' => array('T1', 'T2', 'T3')

Second is to set 'primary_key' of table to corresponding field. 其次是将表的'primary_key'设置为相应的字段。 It can be done in model file or in runtime. 它可以在模型文件中或在运行时中完成。 In my case it can not be done in model because that table also have "correct" association by its 'id' field. 在我的情况下,它不能在模型中完成,因为该表也通过其'id'字段具有“正确”关联。 Setup it runtime is the case but i dislike it because it's not obvious and looks like a hack. 设置运行时是这样的,但我不喜欢它,因为它不明显,看起来像一个黑客。

When i ask this question i thought i missing something obvious but now i understand that CakePHP just can't do that. 当我问这个问题时,我以为我错过了一些明显的东西,但现在我明白CakePHP就是不能这样做。 So i started a bounty hoping that somebody share solution. 所以我开始了一个赏金,希望有人分享解决方案。 If not i will try to read cake sources and redefine model some of method to add ability to define local field near the 'foreign_key' in association definition. 如果不是,我将尝试读取蛋糕源并重新定义模型的一些方法,以添加在关联定义中的'foreign_key'附近定义本地字段的能力。

ForeignKey false ForeignKey假

To have an association which does not use the primary key of the related model in join conditions - the standard way to do that would be to use 'foreignKey' => false . 要在连接条件中使用不使用相关模型的主键的关联 - 标准方法是使用'foreignKey' => false

Ie whereas this association: 即,这种关联:

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

Will generate this sql: 会生成这个sql:

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

Specifying that a foreignKey isn't to be used like so: 指定不要像这样使用foreignKey:

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

Will produce this (invalid) sql: 会产生这个(无效的)sql:

SELECT ... LEFT JOIN profiles on ON ()

From this point, the desired conditions can be specified using the conditions array key: 从这一点开始,可以使用条件数组键指定所需的条件:

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

(Note that the conditions are defined as a string) resulting in: (注意条件定义为字符串)导致:

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

Update: 更新:

Just specify that you don't want to use a foreignKey, then specify the conditions (all within the association: 只需指定您不想使用foreignKey,然后指定条件(所有条件都在关联中:

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

PS - probably a good idea moving forward to try not to be rude to the people helping you. PS - 可能是个好主意,不要对帮助你的人不礼貌。


This is very clearly defined in the CakePHP book: http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#hasmany 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
        )
    );
}

What is a Foreign Key? 什么是外键? :

In the context of relational databases, a foreign key is a field in one table that uniquely identifies a row of another table. 在关系数据库的上下文中,外键是一个表中的一个字段,它唯一地标识另一个表的一行。

Just a workaround that should work for your hasMany relationship when you want to retrieve a User and all his Comments 当您想要检索用户及其所有评论时,只需一种适用于您的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__}'
        )
    );
}

Hope it helps 希望能帮助到你

I struggled with this exact problem for days and the solution that I found (not clearly addressed above) is: The hasMany must have 'foreignKey' => false while the belongsTo MUST ALSO have the 'foreignKey' => false and have the 'conditions' => 'Comment.username = User.username' . 几天来我一直在努力解决这个确切的问题,我找到的解决方案(上面没有明确说明)是: hasMany必须有'foreignKey' => falsebelongsTo必须有'foreignKey' => false并且具有'conditions' => 'Comment.username = User.username' With the conditions as a string not assoc array. conditions为字符串而不是关联数组。 Like so: 像这样:

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

// Comment
public $belongsTo = array(
    'Profile' => array(
        'foreignKey' => false,
        'conditions' => array('Profile.username = Comment.username')
    )
);
public $hasMany = array(
    'Comment' => array(
        'className' => 'T1',
        'foreignKey' => 'username',
        'dependent' => true
    )
);

Note that dependent true would delete all the T1's when T2's were deleted from within cake. 请注意,当从蛋糕内删除T2时,依赖为true将删除所有T1。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM