虚拟字段作为其他模型字段的别名 - SQL:未知列错误

时间:2012-04-18 13:06:08

标签: cakephp cakephp-1.3 cakephp-appmodel

我是现有Cake项目的新手,我们尝试在模型中使用虚拟字段来为另一个模型字段添加别名。在上下文中:

class Product extends AppModel {

    var $name = 'Product';
    var $hasOne = array('ProductPrice');

    var $virtualFields = array(
        'price' => 'ProductPrice.current_price'
    );

    // Typical fields in the database for Product.  id, name, etc.
}

class ProductPrice extends AppModel {
    var $name = 'ProductPrice';
    var $belongsTo = array('Product');

    //  Fields are product_id, current_price
}

ProductPrice模型用于数据库中的视图,该视图包含具有current_price列的不同价格层,允许检索产品的当前价格。通过以下方式访问产品模型时:

$this->Product->find('all' ....);

我在获取价格字段时没有任何问题。问题是如果对Product的查询是通过类似

之类的方式间接完成的
$this->Inventory->find('all');

我们得到:
SQL Error: 1054: Unknown column 'ProductPrice.current_price' in 'field list' [CORE/cake/libs/model/datasources / dbo_source.php,第681行

我知道问题是Inventory查询生成的SQL不会尝试加入ProductPrice视图。我认为这会通过Product模型自动发生,因为它知道它“hasOne”ProductPrice。

我尝试将Inventory模型的“递归”设置为2,1等,但没有成功。

我错过了什么?

1 个答案:

答案 0 :(得分:3)

<强> TLDR:

您无法在VirtualField中使用其他模型中的字段。


其他选项:

如果你正在进行如下查询:

$this->Inventory->find('all');

您可以使用像CakePHP Containable behavior这样的内容来确保您获得所需的数据:

//controller code
$inv = $this->Inventory->getInventory();

//model code
class Inventory extends AppModel {

    public $actsAs = array('Containable');

    public function getInventory() {
        return $this->find('all', array(
            'contain' => array(
                'Product' => array(
                    'ProductPrice'
                )
            )
        ));
    }
}

在上面的代码示例中使用containsable应该以某种格式返回数据,如下所示:

[0] => Array
    (
        [Inventory] => Array
            (
                [id] => 12345
            )
        [Product] => Array
            (
                [0] => Array
                    (
                        [id] => 54321
                        [title] => product A
                    )
                [ProductPrice] => Array
                (
                    [id] => 6789
                    [current_price] => 24.99
                )
            )
//...

当您获得这样的数据时,应该可以轻松访问产品的当前价格。

您也可以在控制器中执行此操作,但最好将您的查询保留在模型中以保持在“Fat Model,Skinny Controller”的口头禅中。如果你真的想将它保存在你的控制器中,你可以这样做:

$inv = $this->find('all', array(
    'contain' => array(
        'Product' => array(
            'ProductPrice'
        )
    )
);

(但是 - 您仍然必须指定模型$ actsAs Containable(每个第一个代码示例)。