我有两个表,两个表中都有字段username
。如何为本地和外部表指定字段名称?
我想要 CakePHP 会做类似的事情
ON (`T1`.`username` = `T2`.`username`)`
结果。没有任何更改的表将按照以下条件连接:
ON (`T1`.`id` = `T2`.`t1_id`)`
设置'foreign_key' = 'username'
属性是不够的,因为它将生成如下查询:
ON (`t1`.`id` = `t2`.`username`)`
我有两个解决方案。第一个是使用"join"属性并动态连接表。在这种情况下,我可以同时设置本地和外部字段。但是,如果我需要将更多表连接到该表,手动连接,我不能再使用 contain,即使该关联设置正确,我也需要手动编写以下连接。所以我每次都需要编写长连接定义,而不是只使用'contain' => array('T1', 'T2', 'T3')
二是将表格的"primary_key"设置为对应字段。它可以在模型文件或运行时中完成。就我而言,它无法在模型中完成,因为该表也具有其'id'
字段的"正确"关联。设置运行时是这种情况,但我不喜欢它,因为它不明显,看起来像一个黑客。
当我问这个问题时,我以为我错过了一些明显的东西,但现在我明白 CakePHP 无法做到这一点。所以我开始了一个赏金,希望有人分享解决方案。如果没有,我将尝试读取蛋糕源并重新定义模型的一些方法,以添加在关联定义中'foreign_key'
附近定义局部字段的能力。
外键假
要有一个在连接条件中不使用相关模型的主键的关联 - 这样做的标准方法是使用 'foreignKey' => false
。
即,鉴于此关联:
class Comment extends AppModel {
public $belongsTo = array(
'Profile' => array(
)
);
}
将生成此 sql:
SELECT ... LEFT JOIN profiles on ON (Profile.id = Comment.profile_id)
指定外键不能像这样使用:
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)
更新:
只需指定您不想使用外键,然后指定条件(全部在关联内:
'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
)
);
}
什么是外键?
在关系数据库的上下文中,外键是 一个表中的字段,用于唯一标识另一个表中的行。
只是一种解决方法,当您想要检索用户及其所有评论时,应该适用于您的许多关系
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__}'
)
);
}
希望对你有帮助
这个确切的问题苦苦挣扎了好几天,我找到的解决方案(上面没有明确解决)是:hasMany
必须有'foreignKey' => false
,而belongsTo
也必须有'foreignKey' => false
并有'conditions' => 'Comment.username = User.username'
。将conditions
作为字符串而不是 assoc 数组。这样:
// 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
)
);
请注意,当从蛋糕中删除 T2 时,依赖 true 将删除所有 T1。