本文介绍了跨插件的两个模型查询时出错 - CakePHP的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 ModelA hasMany ModelB 开发插件.我可以在两个模型中通过简单的 saveAll 正确保存所有数据.

I'm developing a Plugin with ModelA hasMany ModelB. I can save correctly all data with a simply saveAll across the two models.

但是当我尝试跨两个模型执行一个简单的查询时,会发生一些奇怪的事情.

$ModelA = new ModelA();
$result = $ModelA->find('all', array(
    'recursive' => 1
));
pr($result);

Array
(
    [0] => Array
        (
            [ModelA] => Array
                (
                    [id] => 1
                    [field] => value
                )
            [ModelB] => Array
                (
                    [0] => Array
                        (
                            [id] => 1
                            [model_a_id] => 1
                        )
                    [1] => Array
                        (
                            [id] => 2
                            [model_a_id] => 1
                        )
                )
        )
)

但是在 ModelB 上添加条件不起作用:

$ModelA = new ModelA();
$result = $ModelA->find('all', array(
    'recursive' => 1,
    'conditions' => array(
        'ModelB.id' => 2
    )
));
pr($result);
Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'ModelB.id' in 'where clause'

但这项工作:

$ModelA = new ModelA();
$result = $ModelA->ModelB->find('all', array(
    'recursive' => 1,
    'conditions' => array(
        'ModelA.field' => 'value'
    )
));
pr($result);

Array
(
    [0] => Array
        (
            [ModelB] => Array
                (
                    [id] => 2
                    [model_a_id] => 1
                )
            [ModelA] => Array
                (
                    [id] => 1
                    [field] => value
                )
        )
)

有人有想法吗?谢谢!

推荐答案

单独查询

CakePHP 对 hasManyHABTM 关联使用单独的查询.第一个检索主模型数据但不加入关联表,而第二个使用第一个查询结果中的 ID 获取关联记录,然后将这些记录合并到结果中.

Separate queries

CakePHP uses separate queries for hasMany and HABTM associations. The first one retrieves the main model data but doesn't join in associated tables, while the second one uses the IDs from the first queries results to fetch the associated records, which are then merged into the results.

现在的问题是,您的条件将应用于不包含关联模型表的第一个查询,因此会出现错误.

Now the problem is that your conditions will be applied to the first query where the table of the associated model isn't included, hence the error.

反过来,即在 ModelB 上查找,它是一个 belongsTo 关联,其中只使用一个查询,另一个表 em> 加入了该查询,因此条件适用.

The other way around, ie a find on ModelB, it's a belongsTo association, where only one query is being used and the other table is joined into that query, and so the condition applies just fine.

虽然在您的具体示例中更容易查询 ModelB,但也可以通过使用手动定义的连接来解决此问题,如说明书中所述:

While it's easier in your specific example to simply query ModelB instead, this problem can also be solved by using manually defined joins, as described in the Cookbook:

http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#joining-tables

$ModelA->find('all', array(
    'joins' => array(
        array(
            'table' => 'model_bs',
            'alias' => 'ModelB',
            'type' => 'LEFT',
            'conditions' => array('ModelB.id = ModelA.model_b_id')
        )
    ),
    'conditions' => array(
        'ModelB.id' => 2
    )
));

通过这种方式,model_bs 表被连接到第一个查询中,您可以安全地测试 ModelB 上的条件.

This way the model_bs table is joined into the first query and you can safely test for conditions on ModelB.

请注意,如果您不想实际检索 ModelB 的数据(这将再次成为附加查询),则需要将 recursive 设置为-1.

Note that if you wouldn't want to actually retrieve the data of ModelB (which would be an additional query again), you'd need to set recursive to -1.

永远不要像new Model()那样实例化模型,使用ClassRegistry::init()Controller::loadModel(),或者定义要在 Controller::$uses 中加载的模型.

Never instantiate models like new Model(), use ClassRegistry::init(), Controller::loadModel(), or define the models to load in Controller::$uses.

这篇关于跨插件的两个模型查询时出错 - CakePHP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-29 20:26
查看更多