Либо в модели, либо с привязкой «на лету» можно создавать соединения с не первичными ключами следующим образом
public $hasOne = array(
'RelatedModel' => array(
'className' => 'RelatedModel',
'foreignKey' => false,
'conditions' => array(
'`MainModel`.`random_field` = `RelatedModel`.`some_field`'
)
)
}
Хитрость заключается в том, чтобы установить ForeignKey в значение false, чтобы торт ничего не пробовал, а затем установить условия вручную, также обратите внимание, что поля экранируются и в одной строке выглядят как
'`MainModel`.`random_field`' => '`RelatedModel`.`some_field`'
будет выводить
SELECT ..... FROM ... LEFT JOIN ... ON (`MainModel`.`random_field` = '`RelatedModel`.`some_field`')
, который попытается соединить строки, которые == 'RelatedModel
. some_field
' (фактическая строка)