【问题标题】:Virtual Fields as aliases to other Model field - SQL: Unknown Column Error虚拟字段作为其他模型字段的别名 - SQL:未知列错误
【发布时间】:2012-04-29 21:36:43
【问题描述】:

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

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 列允许检索产品的当前价格。通过以下方式访问 Product 模型时:

$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 等,但没有成功。

我错过了什么?

【问题讨论】:

    标签: cakephp cakephp-1.3 cakephp-model


    【解决方案1】:

    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 应该以 something 格式返回数据,如下所示:

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

    当你得到这样的数据时,应该很容易获得产品的当前价格。

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

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

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

    【讨论】:

    • 感谢您的信息。当我有机会时,我会尝试实施并提供反馈。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-15
    • 1970-01-01
    • 1970-01-01
    • 2017-06-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多