0

モデル内で virtualField を使用して別のモデル フィールドのエイリアスを作成しようとしている既存の 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 列を持つさまざまな価格帯を含むデータベース内のビュー用です。次のような方法で Product モデルにアクセスする場合:

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

価格フィールドの取得に問題はありません。問題は、 Product へのクエリが次のようなものを介して間接的に行われる場合です

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

/dbo_source.php、681
SQL Error: 1054: Unknown column 'ProductPrice.current_price' in 'field list' [CORE/cake/libs/model/datasources行目]

Inventory クエリによって生成された SQL が ProductPrice ビューに参加しようとしないことが問題であることはわかっています。これは、Product モデルが "hasOne" ProductPrice であることを認識しているため、Product モデルを介して自動的に発生すると想定しました。

Inventory モデルの "recursive" を 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'
                )
            )
        ));
    }
}

上記のコード例のように containerable を使用すると、次のような形式でデータが返されます

[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 に答える