【问题标题】:CakePHP $hasMany not pulling the data from the $belongsTo model. Join is not createdCakePHP $hasMany 没有从 $belongsTo 模型中提取数据。未创建联接
【发布时间】:2026-02-04 15:30:01
【问题描述】:

我有两个表:internet_access_codesradacct
internet_access_codes 有许多 radacct 记录。
加入是internet_access_codes.code = radacct.username AND internet_access_codes.fk_ship_id = radacct.fk_ship_id

我创建了 2 个模型,想分别使用 $hasMany$belongsTo 以便在获取和 internet_access_codes 记录时拉取相关的 radacct 记录。 p>

代码如下:

class InternetAccessCode extends AppModel{
var $name = 'InternetAccessCode';
var $hasMany = array(
    'Radacct' => array(
        'className' => 'Radacct',
        'foreignKey'=> false,
        'conditions'=> array(
            'InternetAccessCode.code = Radacct.username',
            'InternetAccessCode.fk_ship_id = Radacct.fk_ship_id'
        ),
    )
);

}

class Radacct extends AppModel{
var $name = 'Radacct';
var $useTable = 'radacct';

var $belongsTo = array(
    'InternetAccessCode' => array(
        'className' => 'InternetAccessCode',
        'foreignKey' => false,
        'conditions'=> array(
            'InternetAccessCode.code = Radacct.username',
            'InternetAccessCode.fk_ship_id = Radacct.fk_ship_id'
        )
    ),
);

}

当我 find() 来自 internet_access_codes 的记录时,我希望它也会给我所有相关的 radacct 记录。但是我收到了一个错误,因为它没有进行连接。

这是结果和错误:

Array
(
    [InternetAccessCode] => Array
        (
            [id] => 1
            [code] => 1344444440
            [bandwidth_allowed] => 20000
            [time_allowed] => 30000
            [expires_at] => 31536000
            [cost_price] => 0.00
            [sell_price] => 0.00
            [enabled] => 1
            [deleted] => 0
            [deleted_date] => 
            [fk_ship_id] => 1
            [downloaded_at] => 2011-09-10 22:18:14
        )

    [Radacct] => Array
        (
        )

)

错误: 警告 (512):SQL 错误:1054:未知列 'where 子句'中的'InternetAccessCode.code' [CORE/cake/libs/model/datasources/dbo_source.php,第 684 行]

查询:SELECT Radacct.id, Radacct.fk_ship_id, Radacct.radacctid, Radacct.acctsessionid, Radacct.acctuniqueid, Radacct.username, Radacct.groupname, Radacct.realm, Radacct.nasipaddress, Radacct.nasportid, Radacct.nasporttype, Radacct.acctstarttime, Radacct.acctstoptime, Radacct.acctsessiontime, Radacct.acctauthentic, Radacct.connectinfo_start, Radacct.connectinfo_stop, Radacct.acctinputoctets, Radacct.acctoutputoctets, Radacct.calledstationid, Radacct.callingstationid, Radacct.acctterminatecause, Radacct.servicetype, Radacct.framedprotocol, Radacct.framedipaddress, Radacct.acctstartdelay, Radacct.acctstopdelay, Radacct.xascendsessionsvrkey FROM radacct AS Radacct 其中InternetAccessCode.code = Radacct.usernameInternetAccessCode.fk_ship_id = Radacct.fk_ship_id AND Radacct.deleted 1

在 app_model 中,我还添加了可包含的行为以防万一,但没有任何区别。

【问题讨论】:

    标签: cakephp cakephp-1.3 cakephp-model


    【解决方案1】:

    遗憾的是,cakephp 与外键 =false 和条件的关联并不能很好地工作。关联中的条件应该是 Model.field = 1 或任何其他常量。

    has many association首先查找所有当前模型结果,然后查找所有其他具有当前模型结果foreignKey的模型结果...意味着它进行2次查询。如果您设置条件,它将尝试执行此操作,但由于它没有执行连接,您的查询将找不到另一个表的列。

    解决方案

    使用joins而不是contain或association来强制join你可以找到更多here

    一个如何使用join的例子

    $options['joins'] = array(
        array(
            'table' => 'channels',
            'alias' => 'Channel',
            'type' => 'LEFT',
            'conditions' => array(
                'Channel.id = Item.channel_id',
            )
        ));
    $this->Model->find('all', $options);
    

    可能的解决方案 #2

    BelongsTo 执行自动连接(并非总是如此),您可以从 radaact 中进行查找,该解决方案的坏处是它将列出所有 radacct 并将其 internetAccesCode 关联而不是 internetAccesCode 和所有 radaact 关联.. .. 加入解决方案会给你类似的东西......

    你需要做一个很好的 foreach 来组织你的结果:S 但这并不难....

    希望这能解决您的问题。

    【讨论】: