0

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

我错过了什么?

4

1 回答 1

3

TLDR:

您不能在VirtualField中使用来自不同模型的字段。


其他选项:

如果您正在执行以下查询:

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

您可以使用 CakePHP 的Containable 行为之类的东西来确保获得所需的数据:

//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
                )
            )
//...

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

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

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

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

于 2012-04-18T13:32:01.293 回答